2011-09-27 81 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)。另外你會得到一個叫前綴的方法。該方法將該調用轉發給原始模塊方法。請參閱代碼末尾的示例。