Основываясь на идее построения соглашения об именах для методов внутри модулей, я подготовил автоматизированную версию:
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
).Кроме того, вы получаете метод, называемый префиксом.Этот метод перенаправляет вызов в оригинальный модуль-метод.Смотрите пример в конце кода.