【问题标题】:Ruby - Return A Proc.Call As Variable?Ruby - 将 Proc.Call 作为变量返回?
【发布时间】:2017-10-28 22:19:15
【问题描述】:

我正在尝试创建一个 Ruby 方法: 1. 接受一个接受两个参数的proc作为输入 2. 返回一个带有 one 参数的 proc 作为输出(另一个参数与第一个 proc 一起传入。)

代码如下。我所读到的关于 Ruby 如何处理函数范围的所有内容都表明我应该能够将 proc.call 作为变量返回,但我不明白为什么会得到“意外返回”错误(转载于代码下方)

(我显然是 Ruby 初学者...我的经验主要是在 JavaScript 中,我认为做这种事情的机制要直观得多。)

--

def partial (proc1, val1)
  return Proc.new {|val2| return proc1.call(val1,val2)}
end

adder = Proc.new {|a,b| a + b}

sum_five = partial(adder,5)

sum_five.call(10) # -- expecting 15

# unexpected return
# (repl):13:in `block in partial'
# (repl):20:in `<main>'

【问题讨论】:

    标签: ruby scope proc


    【解决方案1】:

    在 Ruby 中,procs 和 lambdas 以不同的方式处理 return。

    Procs 被设计为在其他 Ruby 控制结构中工作,因此在这种情况下,返回来自控制结构。 Lambda 更像是独立的方法,所以从 lambda 中返回返回值。您会收到一个错误,因为 proc 没有要返回的上下文。

    试试这个:

    def partial (proc1, val1)
      return lambda {|val2| return proc1.call(val1,val2)}
    end
    
    adder = Proc.new {|a,b| a + b}
    
    sum_five = partial(adder,5)
    
    puts sum_five.call(10) # -- expecting 15
    

    【讨论】:

    • 顺便说一下,这个例子中所有的return语句都是多余的,可以在不改变代码含义的情况下删除。
    • 那行得通...谢谢!从您的评论和其他来源中,我感觉到 lambdas 比 procs 更接近 JavaScript 函数(可以在不关心范围的情况下传递)。
    【解决方案2】:

    更短/更简洁的 ruby​​ 语法:

    def composer(proc1, val1)
      -> (val2) { proc1.call(val1, val2) }
    end
    
    adder = -> (a,b) { a + b }
    
    sum_five = composer(adder, 5)
    
    sum_five.call(10)
    

    【讨论】:

      【解决方案3】:

      虽然我不明白它的名字,但 Ruby 已经有一个方法,Proc#curry,它可以做到这一点:

      adder = Proc.new {|a,b| a + b}
      sum_five = adder.curry.call(5)
      sum_five.call(10) # => 15
      sum_five.call(2) # => 7
      

      请注意,因为curry 接受一个可选参数,这是在call 初始过程之前它应该期望的参数数量,所以如果你将你想要的参数作为“默认”传递它'会很奇怪:

      adder = Proc.new {|a,b| a + b}
      sum_five = adder.curry(5) # NOTE: This is incorrect
      sum_five.call(1) # => returns a Proc
      sum_five[1][2][3][4][5] # => 3 (the first 2 arguments got passed, the rest ignored)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-31
        • 2021-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多