【问题标题】:Why does Ruby only allow to refer to methods by symbols when calling to_proc on them?为什么 Ruby 在调用 to_proc 时只允许通过符号引用方法?
【发布时间】:2016-04-24 03:20:03
【问题描述】:

这行得通:

strings = ["1", "2", "3"]
nums = strings.map(&:to_i)

我们看到应用于 Symbol 对象的 & (to_proc 方法) 变成了一个块。 但是,这不起作用:

strings = ["1", "2", "3"]
nums = strings.map(&to_i)
nums = strings.map("to_i".to_sym.to_proc) #...neither does this

为什么它不起作用?没有其他方法可以编写上面的代码吗?我很困惑,因为有两种方法可以访问类的方法:

"1".method(:to_i).call #works as well as
"1".method("to_i").call 

所以方法名可以通过符号或字符串访问。

【问题讨论】:

    标签: ruby symbols proc


    【解决方案1】:

    给定以下有效的 Ruby 示例:

    "to_i".to_sym.to_proc.call("1")
    

    要在 Symbol 上调用 #to_proc 会创建一个接收一个参数的 proc:应该接收对该符号命名的方法的调用的对象。像这样的:

    ->(object) {
      object.send(:to_i)
    }
    

    & 所做的是将#to_proc 返回的块作为适当的调用块传递给被调用的方法。与Enumerable#map一起使用时,最终结果是通过 将为集合上的每个元素调用块并接收 当前迭代元素作为参数传递给块。

    所以["1", "2"].map(&:to_i) 语法是类似的快捷方式 这个:

    block = ->(el) {
      el.send(:to_i)
    }
    
    ["1", "2"].map &block
    

    关于你的例子:

    当您在示例中尝试调用 &to_i 时,Ruby 将尝试调用 一个名为to_i 的变量或方法。由于它不存在于 作用域(它是Array中每个String的方法,不在“全局”作用域内),会产生错误。

    关于另一个示例:"to_i".to_sym.to_proc 将转换 :to_i 进入一个过程,当使用一个参数调用时,将尝试 针对目标调用以符号 (:to_i) 命名的方法 范围。这意味着您可以使用 & 来转换 proc 进入“调用块”:

    ["1", "2"].map(&"to_i".to_sym.to_proc)
    

    【讨论】:

      【解决方案2】:
      nums = strings.map(&to_i)
      

      不起作用,因为 to_i 未在主环境中定义。

      nums = strings.map("to_i".to_sym.to_proc)
      

      不起作用,因为 Proc 实例不是块。块甚至不是对象。

      你可以写:

      nums = strings.map(&"to_i".to_sym)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-18
        • 2010-09-10
        • 1970-01-01
        • 1970-01-01
        • 2013-11-12
        • 2016-09-09
        • 2016-05-21
        • 2013-08-22
        相关资源
        最近更新 更多