考慮以下擴展名(由幾個Rails插件多年來推廣的模式):如何用類宏編程方法擴展Ruby模塊?
module Extension
def self.included(recipient)
recipient.extend ClassMethods
recipient.send :include, InstanceMethods
end
module ClassMethods
def macro_method
puts "Called macro_method within #{self.name}"
end
end
module InstanceMethods
def instance_method
puts "Called instance_method within #{self.object_id}"
end
end
end
如果你想揭露這對每一個類,你可以做到以下幾點:
Object.send :include, Extension
現在您可以定義任何類並使用宏方法:
class FooClass
macro_method
end
#=> Called macro_method within FooClass
而實例可以使用實例方法:
FooClass.new.instance_method
#=> Called instance_method within 2148182320
但即使Module.is_a?(Object)
,您不能在模塊中使用宏方法。
module FooModule
macro_method
end
#=> undefined local variable or method `macro_method' for FooModule:Module (NameError)
這是真實的,即使你明確地包含原始Extension
爲Module
與Module.send(:include, Extension)
。
各個模塊可以包括手動擴展和獲得同樣的效果:
module FooModule
include Extension
macro_method
end
#=> Called macro_method within FooModule
但你如何添加類似於宏的方法對所有的Ruby模塊?
*有*的博客文章。我知道我最近在某處看到過它。仍然好奇爲什麼其他策略不起作用,我不認爲它是一個嚴重的反模式,儘管是一個小小的缺陷,但我確實同意,從根本上說,「在包含延伸行爲時沒有意義Ruby提供了兩者。「 – 2010-06-11 05:33:17
+1爲「貨物裝箱」。 – 2011-07-31 16:48:07
有沒有像你一樣定義「macro_method」的方法,但能夠選擇哪些類可以訪問它? – 2013-09-18 00:19:44