1

send does not work for lambda in Ruby:

>> def mymethod; end
=> :mymethod
>> send('mymethod')
=> nil

>> mylambda = ->{}
=> #<Proc:0x9f2fe28@(pry):136 (lambda)>
>> send('mylambda')
=> NoMethodError: undefined method `mylambda' for main:Object

How do I dynamically call a lambda via a string?

mega6382
  • 9,211
  • 17
  • 48
  • 69
weakish
  • 28,682
  • 5
  • 48
  • 60

4 Answers4

3

You can't access local variables by name without using eval.

Here are a few alternatives you could try:

  • Storing the lambda in a Hash:

    hash = {
      'mylambda' => ->{ 'foo' }
    }
    hash['mylambda'].call # => "foo"
    
  • Storing the lambda in an instance variable:

    @mylambda = ->{ 'foo' }
    instance_variable_get('@mylambda').call # => "foo"
    
  • Creating a temporary method using the lambda

    mylambda = ->{ 'foo' }
    define_method :temp, &mylambda
    send(:temp) # => "foo"
    
August
  • 12,410
  • 3
  • 35
  • 51
2

If you have the correct Binding for the context of your local variable, you can use Binding#local_variable_get to get the value of the local variable. And to get a Binding for the current context, you can use Kernel#binding:

binding.local_variable_get(:mylambda).()
Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
1

You cant use send to invoke lambda. But you can use eval('mylambda').call to invoke

Saravanan
  • 515
  • 3
  • 14
  • you meant outer variable, the variable defined in some other context. ? if that so, how you even try to use send. – Saravanan Nov 23 '14 at 18:03
1

To invoke a lambda method you can either

mylambda.call
# => nil

or

mylambda.()
# => nil

If you want to call the lambda using a string as its variable name you can't - see here for alternatives of how to get other references by their names)

Community
  • 1
  • 1
Uri Agassi
  • 36,848
  • 14
  • 76
  • 93
  • Two more ways: [Proc#[\]](http://www.ruby-doc.org/core-2.1.5/Proc.html#method-i-5B-5D) and [Proc#yield](http://www.ruby-doc.org/core-2.1.5/Proc.html#method-i-yield). – Cary Swoveland Nov 30 '14 at 04:45