Ruby Can';t重新定义一个类';通过包含一个模块来创建实例方法?
我现在心情很好。我可以发誓这是有效的:Ruby Can';t重新定义一个类';通过包含一个模块来创建实例方法?,ruby,Ruby,我现在心情很好。我可以发誓这是有效的: module StubbedGreeting def sayit puts "StubbedGreeting" end end module RegularGreeting def sayit puts "RegularGreeting" end end class Greeting def sayit raise "Gotta catch me!" end end class GreetingIncl
module StubbedGreeting
def sayit
puts "StubbedGreeting"
end
end
module RegularGreeting
def sayit
puts "RegularGreeting"
end
end
class Greeting
def sayit
raise "Gotta catch me!"
end
end
class GreetingIncludes
include RegularGreeting
end
begin
Greeting.send(:include, StubbedGreeting)
Greeting.new.sayit
rescue Exception
puts "Exception raised"
end
GreetingIncludes.send(:include, StubbedGreeting)
GreetingIncludes.new.sayit
这里发生的是Greeting.new.sayit
导致调用rescue
块,忽略StubbedGreeting尝试的覆盖
但是,GreetingIncludes.new.sayit
会产生“StubbedGreeting”,而不是例外
所以一个模块可以覆盖另一个模块的方法,但不能覆盖已经在类中直接定义的方法
我知道如何解决这个问题,我只是觉得很奇怪。当包含模块时,它的方法按方法解析顺序放在类的方法和父类的方法之间。因此,在解析要调用的实际方法时,ruby首先按照以下顺序搜索该方法。如果找到匹配的方法,则中止搜索并使用此方法
- 对象的单例类
- 从最后一个包含到第一个包含在singleton类中的模块
- 对象的类
- 课程中包含的模块
类
类
如您所见,模块确实不能重写在类本身上定义的方法,因为模块在方法解析顺序中位于实际类的后面。如果确实需要重写这样的方法,可以使用alias\u method
或alias\u method\u chain
来“重命名”方法
在即将到来的Ruby 2.0中,将有一个新的类,它将在类之前包含模块,从而实现您想要的功能。但它还没有发布