简体   繁体   English

如何将方法或lambda转换为非lambda proc

[英]How to convert method or lambda to non-lambda proc

As shown in the ruby example below, I can't call a lambda with wrong number of arguments as Proc created from a Method because it is strict about the number of arguments: 如下面的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

How do I get a Proc that is not a lambda from either a Proc that is or from a Method ? 我如何获得一个Proc不是,无论是从一个lambda Proc即或者从一个Method

There is no way to do this. 没有办法做到这一点。

Besides the argument passing, I wonder what you would expect from a return in the method. 除了参数传递,我想知道你对方法中的return会有什么期望。 It can only behave in lambda way... 它只能以lambda方式行事......

If you really have to do this, you will need to build your own block, eg 如果你真的必须这样做,你需要建立自己的块,例如

Proc.new{ a }

For a more generic way, you'll have to check the arity of the method and pass only the required parameters. 对于更通用的方法,您必须检查方法的arity并仅传递所需的参数。

Try wrapping it in a non-lambda Proc , like so: 尝试将其包装在非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

Convert Lambda to Proc Lambda转换为Proc

Here's a work-around that wraps a lambda or a method call in a Proc and uses splat to handle any number of arguments: 这是一个在Proc中包装lambdamethod调用的解决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

This would always work no matter the number of arguments passed; 无论传递的参数数量多少,这都会有效; Extra arguments will be dropped and nil will replace the missing arguments. 额外的参数将被删除, nil将替换缺少的参数。


Example: 例:

# 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!"

Note: There is no direct way to convert a lambda or a method call to a proc. 注意: 没有直接的方法将lambda或方法调用转换为proc。 This is just a workaround and obviously slower than the real deal (because of wrapping one call in another). 这只是一种解决方法,显然比真实交易慢(因为在另一个调用中包含一个调用)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM