[英]How to convert method or lambda to non-lambda proc
如下面的ruby示例所示,我不能将具有错误数量的参数的lambda
称为从Method
创建的Proc
,因为它对参数的数量是严格的:
# method with no args
def a; end
instance_eval(&method(:a))
# ArgumentError: wrong number of arguments (1 for 0)
method(:a).to_proc.call(1, 2, 3)
# ArgumentError: wrong number of arguments (3 for 0)
method(:a).to_proc.lambda?
# => true
我如何获得一个Proc
不是,无论是从一个lambda Proc
即或者从一个Method
?
没有办法做到这一点。
除了参数传递,我想知道你对方法中的return
会有什么期望。 它只能以lambda
方式行事......
如果你真的必须这样做,你需要建立自己的块,例如
Proc.new{ a }
对于更通用的方法,您必须检查方法的arity
并仅传递所需的参数。
尝试将其包装在非lambda Proc
,如下所示:
l = lambda {|a,b| puts "a: #{a}, b: #{b}" }
p = proc {|a,b| l.call(a,b) }
l.lambda?
#=> true
l.arity
#=> 2
l.call("hai")
#=> ArgumentError: wrong number of arguments (1 for 2)
l.call("hai", "bai", "weee", "womp", "woo")
#=> ArgumentError: wrong number of arguments (5 for 2)
p.lambda?
#=> false
p.arity
#=> 2
p.call("hai")
#=> a: hai, b:
p.call("hai", "bai", "weee", "womp", "woo")
#=> a: hai, b: bai
Lambda
转换为Proc
这是一个在Proc
中包装lambda
或method
调用的解决method
,并使用splat处理任意数量的参数:
def lambda_to_proc(lambda)
Proc.new do |*args|
diff = lambda.arity - args.size
diff = 0 if diff.negative?
args = args.concat(Array.new(diff, nil)).take(lambda.arity)
lambda.call(*args)
end
end
无论传递的参数数量多少,这都会有效; 额外的参数将被删除, nil
将替换缺少的参数。
例:
# lambda with two args
some_lambda = -> (a,b) { [a, b] }
# method with no args
def some_method; "hello!"; end
lambda_to_proc(some_lambda).call(5)
# => [5, nil]
lambda_to_proc(method(:some_method)).call(1,2,3)
# => "hello!"
注意: 没有直接的方法将lambda或方法调用转换为proc。 这只是一种解决方法,显然比真实交易慢(因为在另一个调用中包含一个调用)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.