1)更干净/更短
module ClassMethods
def wrap(method)
old = "_#{method}".to_sym
alias_method old, method
define_method method do |*args|
send(old, *args)
end
end
end
class Foo
extend ClassMethods
def bar(arg = 'foo')
puts arg
end
wrap :bar
end
据我所知,如果不重命名,就无法实现这一目标。你可以尝试打电话super
在 - 的里面define_method
堵塞。但首先,请致电super
从一个内define_method
仅当您显式指定参数时才会成功,否则您会收到错误。但即使你打电话,例如super(*args)
, self
在这种情况下将是 Foo 的一个实例。所以打电话给bar
会去超级班Foo
,找不到并最终导致错误。
2)是的,像这样
define_method method do |def_val='foo', *rest|
send(old, def_val, *rest)
end
然而,在 Ruby 1.8 中它是不可能使用一个块define_method
,但这已在 1.9 中修复。如果你使用的是1.9,你也可以使用这个
define_method method do |def_val='foo', *rest, &block|
send(old, def_val, *rest, &block)
end
3)不幸的是,不。alias_method
需要存在作为输入的方法。当 Ruby 方法在解析时出现时,wrap
调用必须在定义之后进行bar
否则alias_method
会引发异常。