将代码插入到类的每个方法的开头 [英] Insert code into the beginning of each method of a class
问题描述
如何动态而轻松地将代码插入类和子类的每个方法的开头,而无需实际手动插入呢?我想要类似宏的内容.
How can I dynamically and easily insert code into the beginning of each method of a class and subclasses without actually inserting it manually? I want something like a macros.
class C1
def m1
@i_am = __method__
end
def m2
@i_am = __method__
end
end
这是我要避免重复的例子之一.
This is one of the examples where I want to avoid repetition.
推荐答案
我最初对这个问题有误解(但在下面的水平线后留了我原来的答案).我相信以下可能是您想要的.
I initially misinterpreted the question (but have left my original answer after the horizontal line below). I believe the following may be what you are looking for.
class C1
[:m1, :m2].each do |m|
define_method(m) do |name|
@i_am = __method__
puts "I'm #{name} from method #{@i_am}"
end
end
end
C1.instance_methods(false)
#=> [:m1, :m2]
c1 = C1.new
#=> #<C1:0x007f94a10c0b60>
c1.m1 "Bob"
# I'm Bob from method m1
c1.m2 "Lucy"
# I'm Lucy from method m2
我的原始解决方案如下.
My original solution follows.
class C1
def add_code_to_beginning(meth)
meth = meth.to_sym
self.class.send(:alias_method, "old_#{meth}".to_sym, meth)
self.class.send(:define_method, meth) do
yield
send("old_#{meth}".to_sym)
end
end
end
Module#alias_method
和 Module#define_method 是私有的;因此需要使用send
.
Module#alias_method
and Module#define_method are private; hence the need to use send
.
c = C1.new
#=> #<C1:0x007ff5e3023650>
C1.instance_methods(false)
#=> [:m1, :m2, :add_code_to_beginning]
c.add_code_to_beginning(:m1) do
puts "hiya"
end
C1.instance_methods(false)
#=> [:m1, :m2, :add_code_to_beginning, :old_m1]
c.m1
# hiya
#=> :m1
这篇关于将代码插入到类的每个方法的开头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!