这更像是一个理论问题,但无论如何我很好奇。我是一个ruby / ruby on rails newbie(但在其他语言/框架方面有很多古老的经验)所以这主要是一个好奇/学习的问题。在此先感谢您的帮助!
我以为我可以使用别名快速扩展到ruby gem,如下所示:
module InstallMyExtension
def self.included(base)
base.class_eval {
alias :some_method_in_gem_without_my_extension :some_method_in_gem
alias :some_method_in_gem :some_method_in_gem_with_my_extension
}
end
def some_method_in_gem_with_my_extension
debugger
# ... do fun stuff here
some_method_in_gem_without_my_extension
end
end
然后在一些初始化文件中我做:
Foo::SomeControllerInFoo.send :include, InstallMyExtension
我在Radiant CMS中学到了这种技术,它在所有地方都使用它来扩展基本行为。我知道这种技术现在已被拒绝了,但它似乎是一种快速尝试一些想法的方法,然后在宝石等上分支等等。
首先,在Rails 3中有一个更好的方法来做这样的快速黑客扩展(这可能只是为了测试一个理论,在分配宝石之前等等)
第二关,它不起作用,有很多我不明白的事情
然后让我解释一下我所看到的奇怪之处:</ p>
即使如果我按照上面的说明执行“include”,当我进入控制台时,我看到一些非常奇怪的行为,我不明白:
1)我键入Foo :: SomeControllerInFoo我得到了Foo :: SomeControllerInFoo,正如我所料。但是,如果第二次运行相同的表达式,Foo :: SomeControllerInFoo会回来未定义!
2)只是为了玩我foo = Foo :: SomeControllerInFoo,然后我可以做foo.send,foo.methods,无论我喜欢什么,但只有我在foo中保存类的副本!那是什么?
3)如果我现在执行foo.send:include,MyExtension调试控制台中的行为是预期的(即gem中包含的原始类现在已经添加了我的行为。)但是在初始化期间运行相同的代码没有效果。没有什么破坏,但控制器没有扩展。
答案 0 :(得分:2)
奇怪的是它不起作用,我只是再次尝试确保这一点(将此代码放在config/initializers
中的文件中)。
我总是使用快捷方式:
alias_method_chain :some_method_in_gem, :my_extension
而不是两个别名行,但它完全相同。
您可以直接使用class_eval
更轻松地覆盖某些方法。再次在初始化器中:
Foo::SomeControllerInFoo.class_eval do
def some_method_in_gem
#your redefinition
end
end
对不起,但没有其他问题的附加值:看起来真的很奇怪和错误。
可以肯定的是,当您想要运行控制器中定义的方法时,请执行以下操作:
c = Foo::SomeControllerInFoo.new
c.method_name