Ruby中的method_missing陷阱 [英] method_missing gotchas in Ruby
本文介绍了Ruby中的method_missing陷阱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
在Ruby中定义method_missing
方法时,有什么需要注意的事情吗?我想知道继承,异常抛出,性能或其他方面是否存在一些不太明显的交互作用.
Are there any things to be careful about when defining the method_missing
method in Ruby? I'm wondering whether there are some not-so-obvious interactions from inheritance, exception throwing, performance, or anything else.
推荐答案
一个显而易见的方法:如果重新定义method_missing
,请始终重新定义respond_to?
.如果method_missing(:sym)
有效,则respond_to?(:sym)
应该始终返回true.有很多库都依赖于此.
A somewhat obvious one: always redefine respond_to?
if you redefine method_missing
. If method_missing(:sym)
works, respond_to?(:sym)
should always return true. There are many libraries that rely on this.
稍后:
一个例子:
# Wrap a Foo; don't expose the internal guts.
# Pass any method that starts with 'a' on to the
# Foo.
class FooWrapper
def initialize(foo)
@foo = foo
end
def some_method_that_doesnt_start_with_a
'bar'
end
def a_method_that_does_start_with_a
'baz'
end
def respond_to?(sym, include_private = false)
pass_sym_to_foo?(sym) || super(sym, include_private)
end
def method_missing(sym, *args, &block)
return foo.call(sym, *args, &block) if pass_sym_to_foo?(sym)
super(sym, *args, &block)
end
private
def pass_sym_to_foo?(sym)
sym.to_s =~ /^a/ && @foo.respond_to?(sym)
end
end
class Foo
def argh
'argh'
end
def blech
'blech'
end
end
w = FooWrapper.new(Foo.new)
w.respond_to?(:some_method_that_doesnt_start_with_a)
# => true
w.some_method_that_doesnt_start_with_a
# => 'bar'
w.respond_to?(:a_method_that_does_start_with_a)
# => true
w.a_method_that_does_start_with_a
# => 'baz'
w.respond_to?(:argh)
# => true
w.argh
# => 'argh'
w.respond_to?(:blech)
# => false
w.blech
# NoMethodError
w.respond_to?(:glem!)
# => false
w.glem!
# NoMethodError
w.respond_to?(:apples?)
w.apples?
# NoMethodError
这篇关于Ruby中的method_missing陷阱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文