命名空间和Mixins
问题描述:
我试图清理我们的命名空间。基本上我们的设置有点像命名空间和Mixins
class myClass
include myModule1
include myModule2
@important_var #critical instance variable
基本上@important_var的是,几乎所有的方法需要获取一个telnet处理程序。这与它现在设置的方式正常工作。不幸的是myModule1 & myModule2变得越来越大。所以我一直在遇到方法的命名空间冲突。
我很想与模块封装如访问方法:
myClass_instance.myModule1.a_method
但我无法弄清楚如何做到这一点或其他一些清洁剂名称间距想法?
答
基于该想法,建立用于模块内的方法中的命名约定我制备的自动版本:
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
)。另外你会得到一个叫前缀的方法。该方法将该调用转发给原始模块方法。请参阅代码末尾的示例。
类和模块必须以大写字母开头。在你的情况下:myClass - > MyClass,myModule1 - > MyModule1 ... – knut
你可以用'm1_'开始MyModule1的每个方法 – knut
很难说没有看到代码,但是从你的描述来看,它听起来像需要一些重构。 - 您是否可以将您的方法直接分解为需要@important_var的较低级别的管道,并将其与其他人隔离开来? - 班级真的有责任吗?还是可以分开?等等 –