Ruby 的查找方法 - 参数?

Ruby's find method - argument?

我正在做一些探索。关于 Ruby 的

.find(ifnone = nil) { |obj| block } 
方法:通过阅读 documentation,在我看来你应该能够将方法作为参数传递 运行在没有匹配指定条件的情况下。

它说:

"calls ifnone and returns its result when it is specified, or returns nil otherwise."

这似乎适用于我创建的任何已经 return 为零的方法,例如:

 
def message
 puts 'No match.'
end
No match.
=>nil

如果我使用的方法可以做 return 事情,请说:

def message
 p 'No match.'
end

我会得到:

"No match."
NoMethodError: undefined method `call' for "No match.":String

有好心人可以准确地向我解释什么样的 arg/method 实际上应该传递给这里的 find 方法吗?谢谢。

很高兴您提出这个问题。我从来没有想过 find 方法的那个论点,因为我以前从来没有真正使用过它。相反,我总是忽略它,直到你在这里提到它。

您将传递给可枚举的参数,例如 find,将是 lambda 或 proc。如果没有找到匹配项,而不是 return 默认 nil,它会 return lambda/proc。

举个简单的例子:

nums = [1, 2, 3, 4]
nums.find(lambda {raise ArgumentError, "No matches found"}) { |num| num == 5 }

> ArgumentError: No matches found

同样,你也可以传递一个Proc..

nums = [1, 2, 3, 4]
arg = Proc.new {"No matches found"}
nums.find(arg) { |num| num == 5 }

> "No matches found"

只需快速编辑,您就可以 return lambda 或 proc 中的任何值,无论是引发错误还是 returning 值。我想象引发错误和错误处理是一种常见的用法

Edit2:删除了 link 解释此方法的文章。博客 post 似乎已被删除 :(

NoMethodError: undefined method `call' for "No match.":String

这是一个很大的提示。 find 想要一个可调用对象 - 即响应 #call 的对象。由于 Ruby 是鸭子类型的,所有这些都可以工作:

def message_method
  puts "yo"
end
...find(method(:message_method)) { ... }

module MessageModule
  def self.call
    puts "yo"
  end
end
...find(MessageModule) { ... }

class MessageClass
  def call
    puts "yo"
  end
end
...find(MessageClass.new) { ... }

message_proc = Proc.new { puts "yo" }
...find(message_proc) { ... }

lambda 是另一种构造 Proc 对象的方法;不同的语法导致语义略有不同,但要点是 lambda 也同样有效。)

还有一个反常的例子(作废):

require 'continuation'
callcc do |notfound|
  ...find(notfound) { ... }
  ...
end