如何替换 Rails 控制台中的现有类?

B S*_*ven 3 ruby ruby-on-rails class

在控制台中:

class Logger
end
l = Logger.new
Run Code Online (Sandbox Code Playgroud)

抛出错误:ArgumentError: wrong number of arguments (0 for 1) from /home/zzz/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/logger.rb:268:in 'initialize'

为什么要使用 Logger /home/zzz/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/logger.rb

KL-*_*L-7 5

我将尝试回答你的第二个问题。那么,为什么 Ruby 使用其他Logger类而不是您尝试自己定义的类呢?

Ruby 的基本特性之一是重新开放类。假设您的应用程序中已经定义并加载了一些类:

class A
  def foo
    puts 'foo'
  end
end

A.new.foo
#=> foo
Run Code Online (Sandbox Code Playgroud)

如果之后 Ruby 解释器遇到类似的情况:

class A
  def bar
    puts 'bar'
  end
end
Run Code Online (Sandbox Code Playgroud)

它不会重新定义 class A,而只是将此定义附加到前一个定义中。在结果中,已定义的类A获得新的实例方法bar

A.new.foo # still works
#=> foo
A.new.bar # new method
#=> bar
Run Code Online (Sandbox Code Playgroud)

由于 Ruby 处理方法调用的方式,在类的第二次定义(实际上是重新打开)之前A初始化的所有类实例也会获得这个新方法。因此,每次重新打开一个类时,都会向该类本身以及该类的所有先前初始化的实例添加新功能。Abar

重新打开类还允许重写现有类的方法:

class A
  def foo
    puts 'new foo'
  end
end

A.new.foo
#=> new_foo
Run Code Online (Sandbox Code Playgroud)

考虑到该功能以及 Rails 已经Logger为您加载了标准类这一事实,您的定义仅重新打开该类,但甚至不会更改任何内容。