How to convert a method or lambda to a non-lambda process

As shown in the Ruby example below, I cannot call lambda with the wrong number of arguments like Proc created from Method , because it is strict regarding the number of arguments:

 # 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 Proc that is or from Method ?

+7
source share
3 answers

There is no way to do this.

Besides passing arguments, I wonder what you expect from the return method in the method. It can only behave in a lambda way ...

If you really need to do this, you will need to create your own block, for example.

 Proc.new{ a } 

For a more general way, you will need to check the arity method and pass only the required parameters.

+2
source

Try wrapping it in non-lambda Proc , for example:

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

Convert Lambda to Proc

Here's a workaround that wraps a call to Lambda or method in Proc and uses splat to handle any number of arguments:

 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 will always work regardless of the number of arguments passed; Additional arguments will be removed, and nil will replace the missing arguments.


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 method call to proc. This is just a workaround, and obviously slower than the real deal (due to wrapping one call in another).

0
source

All Articles