我會傾向於預先考慮到類動態創建匿名模塊,其實例方法使用super
調用類的同名的實例方法中,印刷後方法輸入消息以及打印方法退出消息之前。
讓我們開始創建一個具有兩個實例方法的類,其中一個在參與時通過一個塊。
class C
def mouse(nbr_mice, impairment)
puts "%d %s mice" % [nbr_mice, impairment]
end
def hubbard(*args)
puts yield args
end
end
C.ancestors
#=> [C, Object, Kernel, BasicObject]
c = C.new
c.mouse(3, 'blind')
# 3 blind mice
c.hubbard('old', 'mother', 'hubbard') { |a| a.map(&:upcase).join(' ') }
# OLD MOTHER HUBBARD
現在我們構建一個方法,創建匿名模塊並將其前置到類中。
def loggem(klass, *methods_to_log)
log_mod = Module.new do
code = methods_to_log.each_with_object('') { |m,str| str <<
"def #{m}(*args); puts \"entering #{m}\"; super; puts \"leaving #{m}\"; end\n" }
class_eval code
end
klass.prepend(log_mod)
end
現在,我們準備調用該方法等於給該模塊將前置,並會記錄在該類的實例方法的類的參數。
loggem(C, :mouse, :hubbard)
C.ancestors
#=> [#<Module:0x007fedab9ccf48>, C, Object, Kernel, BasicObject]
c = C.new
c.method(:mouse).owner
#=> #<Module:0x007fedab9ccf48>
c.method(:mouse).super_method
#=> #<Method: Object(C)#mouse>
c.method(:hubbard).owner
#=> #<Module:0x007fedab9ccf48>
c.method(:hubbard).super_method
#=> #<Method: Object(C)#hubbard>
c.mouse(3, 'blind')
# entering mouse
# 3 blind mice
# leaving mouse
c.hubbard('old', 'mother', 'hubbard') { |a| a.map(&:upcase).join(' ') }
# entering hubbard
# OLD MOTHER HUBBARD
#leaving hubbard
見Module::new和Module#prepend。
正是我所需要的。謝謝 – amadain