简体   繁体   English

如何替换Rails控制台中的退出类?

[英]How to replace exiting class in Rails console?

In console: 在控制台中:

class Logger
end
l = Logger.new

Throws error: 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' 引发错误: 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'

Why is it using the Logger in /home/zzz/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/logger.rb ? 为什么在/home/zzz/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/logger.rb使用记录器?

I'll try to answer to your second question. 我将尝试回答您的第二个问题。 So, why is Ruby using some other Logger class and not the one you tried to define yourself? 那么,为什么Ruby使用其他Logger类而不是您尝试定义自己的类?

One of the fundamental features of Ruby is re-opening of classes. Ruby的基本功能之一是重新打开类。 Let's say you have some class that is already defined and loaded in your app: 假设您有一些已经在您的应用中定义并加载的类:

class A
  def foo
    puts 'foo'
  end
end

A.new.foo
#=> foo

If after that Ruby interpreter encounters something like: 在那之后,如果Ruby解释器遇到类似这样的事情:

class A
  def bar
    puts 'bar'
  end
end

it doesn't redefine class A , but simply appends this definition to the previous one. 它不会重新定义A类,而只是将此定义附加到上一个定义。 In the result already defined class A gets new instance method bar : 在结果中,已定义的类A获得新的实例方法bar

A.new.foo # still works
#=> foo
A.new.bar # new method
#=> bar

Because of the way Ruby handles methods calling, all instances of class A that were initialized before the second definition (actually, re-opening) of class A also get this new method bar . 由于的方式处理的Ruby方法调用,该类的所有实例A说是类的第二个定义(实际上,重开)初始化之前 A也得到这种新方法bar So every time you reopen a class you add new functionality to the class itself and to all previously initialized instances of this class. 因此,每次您重新打开一个类时,都会向该类本身以及该类的所有先前初始化的实例中添加新功能。

Classes reopening also allows rewriting methods of an existing class: 重新打开类也可以重写现有类的方法:

class A
  def foo
    puts 'new foo'
  end
end

A.new.foo
#=> new_foo

With that feature in mind and the fact that Rails has already loaded standard Logger class for you, your definition only reopens the class, but doesn't even change anything. 考虑到该功能以及Rails已经为您加载了标准Logger类的事实,您的定义只会重新打开该类,甚至不会更改任何内容。

That class was already loaded, presumably because rails was using it: you haven't redefined the class, you were merely re-opening it. 该类已经加载,可能是因为Rails正在使用它:您没有重新定义该类,只是在重新打开它。

You could remove the existing class 您可以删除现有的课程

Object.send(:remove_const, :Logger)

In this case the class formerly known as Logger still exists, it just isn't bound to the constant Logger any more, so when you do 在这种情况下,以前称为Logger的类仍然存在,只是不再与常量Logger绑定,因此当您执行

class Logger
end

you'll be creating a new class not reopening the old one. 您将创建一个新类,而不重新打开旧类。 You may of course end up breaking code that assumed the presence of the old Logger class. 当然,您可能最终破坏了假定存在旧Logger类的代码。

If you're doing this in tests, you may be interested in the new constant stubbing in rspec 2.11 如果您在测试中执行此操作,则可能会对rspec 2.11中的新常量存根感兴趣

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM