【问题标题】:Ruby's find method - argument?Ruby 的 find 方法 - 参数?
【发布时间】:2016-02-05 19:16:58
【问题描述】:

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

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

上面写着:

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

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

定义消息 提出“不匹配”。 结尾
No match.
=>nil

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

定义消息 p '不匹配。 结尾

我会得到:

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

是否有人好心地向我解释一下实际上应该将哪种类型的 arg/方法传递给 find 方法?谢谢。

【问题讨论】:

    标签: ruby find arguments


    【解决方案1】:

    很高兴您提出这个问题。我从没想过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:删除了解释此方法的文章的链接。看来博文已被删除:(

    【讨论】:

    • 我也很想忽略这个论点。很高兴我们都学到了一些东西!我记得不久前看到过那个链接的文章,但找不到了。谢谢:D
    【解决方案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
    

    【讨论】:

    • 虽然这看起来很透彻,但我对它的理解却较少。我认为我还不够先进,无法充分利用所有信息。
    • 哈哈,对不起。主要的一点是 - 它可以是任何具有call 方法的东西。这包括ProcMethod 对象,它们的call 方法执行它们包装的代码。
    猜你喜欢
    • 2011-02-14
    • 2013-02-07
    • 1970-01-01
    • 2011-08-15
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 2020-04-15
    • 2011-12-19
    相关资源
    最近更新 更多