【发布时间】:2012-11-27 09:36:54
【问题描述】:
定义respond_to_missing? 而不是定义respond_to? 有什么意义?如果为某个类重新定义 respond_to? 会出现什么问题?
【问题讨论】:
标签: ruby metaprogramming
定义respond_to_missing? 而不是定义respond_to? 有什么意义?如果为某个类重新定义 respond_to? 会出现什么问题?
【问题讨论】:
标签: ruby metaprogramming
没有定义respond_to_missing?,尝试通过method获取方法会失败:
class Foo
def method_missing name, *args
p args
end
def respond_to? name, include_private = false
true
end
end
f = Foo.new
f.bar #=> []
f.respond_to? :bar #=> true
f.method :bar # NameError: undefined method `bar' for class `Foo'
class Foo
def respond_to? *args; super; end # “Reverting” previous redefinition
def respond_to_missing? *args
true
end
end
f.method :bar #=> #<Method: Foo#bar>
Marc-André(Ruby 核心提交者)有一个很好的blog post on respond_to_missing?。
【讨论】:
respond_to? 有什么用。它有合法的用例吗?
respond_to? 应该始终是被调用的方法。你不应该直接打电话给respond_to_missing?。
respond_to_missing? 不应该默认返回 true。相反,它应该类似于 check_if_method_meet_condition || super 。另一件事是它通常被定义为respond_to_missing(method_name, include_private = false)
method_missing 存在(并且从不引发NameError 本身),那么respond_to_missing? 返回true 总是很有意义。但这只是一个人为的例子。至于后一点:我是懒惰的,这里从来没有使用过参数。
如果您要覆盖 method_missing,最好创建 respond_to_missing?。这样,即使没有显式声明,该类也会告诉您所调用的方法存在。
respond_to?可能不应该被覆盖:)
【讨论】: