我想补充一些关于他们类似关键字的行为,因为答案更多的是关于where 而不是how;答案在于 Ruby 的复杂元编程能力。可以将它们用作使用钩子的关键字;method_added
Ruby 中的钩子是在特定事件(即钩子的名称)发生时调用的函数。重要的是method_added
钩子接收已定义方法的名称作为其参数:这样,就可以修改它的行为。
例如,你可以使用这个钩子来定义类似于 Python 的装饰器的行为;重要的部分是,与private
andprotected
方法不同,这种类似装饰器的方法应该定义一个method_added
未定义自身的 a:
class Module
def simple_decorator
eigenclass = class << self; self; end
eigenclass.class_eval do
define_method :method_added do |name|
eigenclass.class_eval { remove_method :method_added }
old_name = 'old_' + name.to_s
alias_method old_name, name
class_eval %Q{
def #{name}(*args, &block)
p 'Do something before call...'
#{old_name}(*args, &block)
p '... and something after call.'
end
}
end
end
end
end
class UsefulClass
simple_decorator
def print_something
p "I'm a decorated method :)"
end
def print_something_else
p "I'm not decorated :("
end
end
a = UsefulClass.new
a.print_something
a.print_something_else
simple_decorator
看起来像一个语言关键字并且表现得像private
; 但是,因为它移除了method_added
钩子,所以它只适用于紧随其后的方法定义。