Ruby - 将Proc.Call作为变量返回?

时间:2017-10-28 22:19:16

标签: ruby scope proc

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

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

(我显然是Rubyist的开始......我的经验主要是在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>'

3 个答案:

答案 0 :(得分:2)

在Ruby中,procs和lambdas对待返回的方式不同。

Procs被设计为在其他Ruby控制结构中工作,因此在该上下文中,返回来自控制结构。 Lambdas更像是独立的方法,因此返回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

答案 1 :(得分:0)

更短/更清晰的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)

答案 2 :(得分:0)

虽然我不明白它的名字,但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)