考虑以下扩展名(由几个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