我想使用 class_eval 扩展某些类的功能。我想强制类从其他类继承一些方法。
IE:
SomeClass.class_eval do
# force inheritence from some other class
end
实现它的最佳方法是什么?
我想使用 class_eval 扩展某些类的功能。我想强制类从其他类继承一些方法。
IE:
SomeClass.class_eval do
# force inheritence from some other class
end
实现它的最佳方法是什么?
如果在这里覆盖现有功能是一项硬性要求,您需要在包含的模块中定义这些现有方法。
class SomeClass
include DefaultBehaviour
end
module DefaultBehaviour
def run
puts "ran default"
end
end
module AlternateBehaviour
def run
puts "ran alternate"
end
end
SomeClass.class_eval {
include AlternateBehaviour
}
SomeClass.new.run #=> "ran alternate"
原因是因为 ruby 的方法查找路径。
它从 SomeClass -> Object 开始。
当您包含 AlternateBehaviour 时,它变为 SomeClass -> AlternateBehaviour -> Object。所以直接在 SomeClass 上定义的方法仍然优先。
但是,如果在 DefaultBehaviour 上定义了这些方法,则查找路径将变为 SomeClass -> AlternateBehaviour -> DefaultBehaviour -> Object,因此您的替代方法优先。最近包含的模块是最高优先级的。
在您无法控制原始类的情况下,您可以改为:
module AlternateBehaviour
def self.included(base)
base.send(:remove_method, :run)
end
def run
puts "ran alternate"
end
end
虽然在这一点上,人们开始怀疑你是否可以通过做
SomeClass.class_eval {
def run
"ran alternate"
end
end