2017-10-28 106 views
0

我试图创建一个Ruby方法: 1.接受为输入,它接受参数和 2.返回作为输出一个PROC这需要一个参数(另一说法被传递与PROC第一个处理程序)Ruby - 将Proc.Call作为变量返回?

下面的代码。我读过的关于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>' 

回答

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 
+0

顺便说一句,在所有return语句这个例子是多余的,可以在不改变代码含义的情况下删除。 –

+0

这工作......谢谢!从您的评论和其他来源,我得到的感觉是,lambda比JavaScript更加接近特效(可以通过对范围的关注较少来传递)。 –

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) 
0

虽然我不知道它的名字,林心如已经有一个方法,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之前预计荷兰国际集团的初始PROC,所以如果你传递你想要的“默认”的说法它会工作怪异:

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)