我很困惑何时使用这些方法。
来自respond_to?
文档:
如果 obj 响应给定方法,则返回true。私人方法 仅在可选的第二个参数中包含在搜索中 评估为真。
如果该方法未实现,如Windows上的Process.fork, GNU / Linux等上的File.lchmod,返回false。
如果没有定义方法,则response_to_missing?方法被称为和 结果返回。
respond_to_missing?
:
Hook方法返回 obj 是否可以响应 id 方法或 不
请参阅#respond_to?。
两种方法都有两个参数 两种方法似乎都是一样的(检查某个对象是否响应给定的方法)所以为什么我们应该使用(have)两者?
定义'resond_to_missing?`让你有能力采取方法:
class A
def method_missing name, *args, &block
if name == :meth1
puts 'YES!'
else
raise NoMethodError
end
end
def respond_to_missing? name, flag = true
if name == :meth1
true
else
false
end
end
end
[65] pry(main)> A.new.method :meth1
# => #<Method: A#meth1>
为什么respond_to?
无法做到这一点?
respond_to?
检查方法是否在:
respond_to_missing?
检查方法是否为:
method_missing
:通过一系列可能的方法:
def method_missing name, *args, &block
arr = [:a, :b, :c]
if arr.include? name
puts name
else
raise NoMethodError
end
end
将其委托给不同的对象:
class A
def initialize name
@str = String name
end
def method_missing name, *args, &block
@str.send name, *args, &block
end
end
2。其他我不知道的方式。
从1.9.3开始(我记得公平)仅定义respond_to_missing?
但仅使用respond_to?
我是对的吗?我错过了什么吗?纠正所有错误和/或回答问题中提出的问题。
答案 0 :(得分:4)
respond_to_missing?
。这将使Ruby解释器更好地理解新方法的存在。
事实上,如果不使用respond_to_missing?
,则无法使用method
获取该方法。
Marc-André posted a great article关于respond_to_missing?
。
为了响应?要返回true,可以将其专门化,如下所示:
class StereoPlayer # def method_missing ... # ... # end def respond_to?(method, *) method.to_s =~ /play_(\w+)/ || super end end p.respond_to? :play_some_Beethoven # => true
这样更好,但它仍然没有使play_some_Beethoven的行为与方法完全相同。事实上:
p.method :play_some_Beethoven # => NameError: undefined method `play_some_Beethoven' # for class `StereoPlayer'
Ruby 1.9.2引入了
respond_to_missing?
,它为问题提供了一个干净的解决方案。而不是专门化respond_to?
一个专门化respond_to_missing?
。这是一个完整的例子:class StereoPlayer # def method_missing ... # ... # end def respond_to_missing?(method, *) method =~ /play_(\w+)/ || super end end p = StereoPlayer.new p.play_some_Beethoven # => "Here's some_Beethoven" p.respond_to? :play_some_Beethoven # => true m = p.method(:play_some_Beethoven) # => #<Method: StereoPlayer#play_some_Beethoven> # m acts like any other method: m.call # => "Here's some_Beethoven" m == p.method(:play_some_Beethoven) # => true m.name # => :play_some_Beethoven StereoPlayer.send :define_method, :ludwig, m p.ludwig # => "Here's some_Beethoven"
另见Always Define respond_to_missing? When Overriding method_missing。