gpt4 book ai didi

ruby - respond_to 和 respond_to_missing 有何不同?

转载 作者:数据小太阳 更新时间:2023-10-29 07:16:58 27 4
gpt4 key购买 nike

我对何时使用这些方法感到困惑。来自 respond_to? 文档:

Returns true if obj responds to the given method. Private methods are included in the search only if the optional second parameter evaluates to true.

If the method is not implemented, as Process.fork on Windows, File.lchmod on GNU/Linux, etc., false is returned.

If the method is not defined, respond_to_missing? method is called and the result is returned.

respond_to_missing?:

Hook method to return whether the obj can respond to id method or not.

See #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>

为什么 respond_to? 不能这样做?

我的猜测:

respond_to? 检查方法是否在:

  1. 当前对象。
  2. 父对象。
  3. 包含的模块。

respond_to_missing? 检查方法是否:

  1. 通过method_missing定义:

通过一系列可能的方法:

def method_missing name, *args, &block
arr = [:a, :b, :c]
if arr.include? name
puts name
else
raise NoMethodError
end
end

委托(delegate)给不同的对象:

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?

最后的问题:

我说的对吗?我错过了什么吗?更正所有错误的内容和/或回答此问题中提出的问题。

最佳答案

respond_to_missing? 应该在您使用方法缺失技术提供其他方法时更新。这将使 Ruby 解释器更好地理解新方法的存在。

事实上,如果不使用respond_to_missing?,您将无法使用method 获取方法。 .

Marc-André posted a great article关于 respond_to_missing?

In order for respond_to? to return true, one can specialize it, as follows:

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

This is better, but it still doesn’t make play_some_Beethoven behave exactly like a method. Indeed:

p.method :play_some_Beethoven
# => NameError: undefined method `play_some_Beethoven'
# for class `StereoPlayer'

Ruby 1.9.2 introduces respond_to_missing? that provides for a clean solution to the problem. Instead of specializing respond_to? one specializes respond_to_missing?. Here’s a full example:

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 .

关于ruby - respond_to 和 respond_to_missing 有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20731167/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com