Dar*_*dza 5 ruby metaprogramming
我对何时使用每种方法感到困惑。从respond_to?文档:
如果obj响应给定的方法,则返回true 。仅当可选的第二个参数的值为true时,私有方法才包含在搜索中。
如果未实现该方法,例如Windows上的Process.fork,GNU / Linux上的File.lchmod等,则返回false。
如果未定义方法,则response_to_missing?方法被调用并返回结果。
和respond_to_missing?:
Hook方法,返回obj是否可以响应id方法。
请参阅#respond_to?。
两种方法都带有两个参数。
两种方法似乎都是同一件事(检查某个对象是否响应给定的方法),为什么我们应该同时使用(拥有)这两种方法呢?
定义“ 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>
Run Code Online (Sandbox Code Playgroud)
为什么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
Run Code Online (Sandbox Code Playgroud)
将其委托给其他对象:
class A
def initialize name
@str = String name
end
def method_missing name, *args, &block
@str.send name, *args, &block
end
end
Run Code Online (Sandbox Code Playgroud)
2。我不知道的其他方式。
从1.9.3开始(我记得还不错)仅定义respond_to_missing?但仅使用respond_to?
我对吗?我错过了什么吗?纠正所有不良情况和/或回答此问题中提出的问题。
respond_to_missing?当您使用方法缺失技术提供其他方法时,应该更新。这将使 Ruby 解释器更好地理解新方法的存在。
事实上,如果不使用respond_to_missing?,您将无法使用 来获取该方法method。
Marc-Andr\xc3\xa9 发表了一篇关于respond_to_missing?.
\n\n\n为了respond_to?要返回 true,可以将其专门化,如下所示:
\n\nRun Code Online (Sandbox Code Playgroud)\n\nclass StereoPlayer\n # def method_missing ...\n # ...\n # end\n\n def respond_to?(method, *)\n method.to_s =~ /play_(\\w+)/ || super\n end\nend\np.respond_to? :play_some_Beethoven # => true\n这更好,但它仍然不能使 play_some_Beethoven 的行为与方法完全相同。的确:
\n\nRun Code Online (Sandbox Code Playgroud)\n\np.method :play_some_Beethoven\n# => NameError: undefined method `play_some_Beethoven\'\n# for class `StereoPlayer\'\nRuby 1.9.2 的引入
\n\nrespond_to_missing?为该问题提供了一个干净的解决方案。与其专一,不如respond_to?专一respond_to_missing?。Here\xe2\x80\x99s 是一个完整的示例:Run Code Online (Sandbox Code Playgroud)\nclass StereoPlayer\n # def method_missing ...\n # ...\n # end\n\n def respond_to_missing?(method, *)\n method =~ /play_(\\w+)/ || super\n end\nend\n\np = StereoPlayer.new\np.play_some_Beethoven # => "Here\'s some_Beethoven"\np.respond_to? :play_some_Beethoven # => true\nm = p.method(:play_some_Beethoven) # => #<Method: StereoPlayer#play_some_Beethoven>\n# m acts like any other method:\nm.call # => "Here\'s some_Beethoven"\nm == p.method(:play_some_Beethoven) # => true\nm.name # => :play_some_Beethoven\nStereoPlayer.send :define_method, :ludwig, m\np.ludwig # => "Here\'s some_Beethoven"\n
另请参见始终定义 respond_to_missing?当重写 method_missing 时。
\n| 归档时间: |
|
| 查看次数: |
2365 次 |
| 最近记录: |