命名空间和Mixins [英] Namespaces and Mixins
问题描述
我正在尝试清理我们的名称空间.基本上我们的设置有点像
I'm trying to clean up our namespaces. Basically our setup is somewhat like
class myClass
include myModule1
include myModule2
@important_var #critical instance variable
基本上@important_var是几乎所有方法都需要使用的telnet处理程序.现在安装的方式可以很好地工作.不幸的是myModule1& myModule2越来越庞大.因此,我不断遇到方法的名称空间冲突.
Basically @important_var is a telnet handler that almost all methods need to get at. This works fine with the way it is setup right now. Unfortunately myModule1 & myModule2 are getting huge. So I keep running into namespace collisions for the methods.
我很想使用模块包装器访问方法,例如:
I'd love to access methods with a module wrapper eg:
myClass_instance.myModule1.a_method
但是我不知道如何做到这一点或其他一些更清洁的名称间隔想法?
But I can't figure out how to do this or some other cleaner name spacing idea?
推荐答案
基于为模块内部方法建立命名约定的想法,我准备了一个自动化版本:
Based on the idea to build a naming convention for the methods inside the modules I prepared a automated version:
module MyModule1
def m; "M1#m <#{@important_var }>"; end
#method according naming convention
def m1_action; "M1#m1 <#{@important_var }>"; end
end
module MyModule2
def m; "M2#m <#{@important_var }>"; end
#method according naming convention
def m2_action; "M2#m2 <#{@important_var }>"; end
end
class MyClass
#add prefix to each method of the included module.
def self.myinclude( mod, prefix )
include mod
#alias each method with selected prefix
mod.instance_methods.each{|meth|
if meth.to_s[0..prefix.size-1] == prefix
#ok, method follows naming convention
else #store method as alias
rename = "#{prefix}#{meth}".to_sym
alias_method(rename, meth)
puts "Wrong name for #{mod}##{meth} -> #{rename}"
end
}
#define a method '<<prefix>> to call the methods
define_method(prefix){ |meth, *args, &block | send "#{prefix}#{meth}".to_sym *args, &block }
end
myinclude MyModule1, 'm1_'
myinclude MyModule2, 'm2_'
def initialize
@important_var = 'important variable' #critical instance variable
end
end
###################
puts "-------Test method calls--------"
m = MyClass.new
p m.m1_action
p m.m2_action
p m.m #last include wins
puts "Use renamed methods"
p m.m1_m
p m.m2_m
puts "Use 'moduled' methods"
p m.m1_(:m)
p m.m2_(:m)
myinclude
包括模块并检查每种方法是否以定义的前缀开头.如果没有,则定义该方法(通过alias
).另外,您会得到一个称为前缀的方法.此方法将调用转发到原始模块方法.参见代码末尾的示例.
myinclude
includes the module and checks, if each method begins with a defined prefix. If not the method is defined (via alias
). In addition you get a method called like the prefix. This method forwards the call to the original module-method. See example in the code end.
这篇关于命名空间和Mixins的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!