2011-09-27 75 views
0

我试图清理我们的命名空间。基本上我们的设置有点像命名空间和Mixins

class myClass 
include myModule1 
include myModule2 

@important_var #critical instance variable 

基本上@important_var的是,几乎所有的方法需要获取一个telnet处理程序。这与它现在设置的方式正常工作。不幸的是myModule1 & myModule2变得越来越大。所以我一直在遇到方法的命名空间冲突。

我很想与模块封装如访问方法:

myClass_instance.myModule1.a_method 

但我无法弄清楚如何做到这一点或其他一些清洁剂名称间距想法?

+0

类和模块必须以大写字母开头。在你的情况下:myClass - > MyClass,myModule1 - > MyModule1 ... – knut

+0

你可以用'm1_'开始MyModule1的每个方法 – knut

+0

很难说没有看到代码,但是从你的描述来看,它听起来像需要一些重构。 - 您是否可以将您的方法直接分解为需要@important_var的较低级别的管道,并将其与其他人隔离开来? - 班级真的有责任吗?还是可以分开?等等 –

回答

1

基于该想法,建立用于模块内的方法中的命名约定我制备的自动版本:

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)。另外你会得到一个叫前缀的方法。该方法将该调用转发给原始模块方法。请参阅代码末尾的示例。