Ruby的find方法 - 参数?

时间:2015-11-05 03:46:28

标签: ruby find arguments

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

.find(ifnone = nil) { |obj| block } 
方法:从阅读documentation开始,在我看来,你应该能够将一个方法作为一个参数传递给将在如果指定条件没有匹配的情况。

它说:

  

"调用 ifnone 并在指定时返回其结果,或返回   否则nil。"

这似乎适用于我创建的任何已经返回nil的方法,比如说:

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

如果我使用的方法确实返回了某些内容,请说:

def message
 p 'No match.'
end

我会得到:

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

有人会善意地向我解释究竟在这里将什么样的arg /方法传递给find方法?感谢。

2 个答案:

答案 0 :(得分:4)

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

你传递给可枚举的参数,如find,将是一个lambda或proc。如果没有找到匹配项,则返回默认nil,而不是返回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"

只需快速编辑,即可返回lambda或proc中的任何值,无论是引发错误还是返回值。我想提出错误和错误处理是常见的用途

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

答案 1 :(得分:2)

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