Ruby lambdas and each and enumerators


When I define and assign a lambda like this

my_lambda = lambda{ |key, value| puts key, value }

can I call an array or hash each method that return an enumerator and pass my lambda as body of the each,

{ :one=>1, :two=> 2 }.each my_lambda

like this ?


Honestly I felt the lack of an interactive debugger and of a tool/reflector to dig into the each method implementation here.
A more experienced Ruby programmer could tell me where to find them probably.


That call gave me an error, wrong number of parameters (1 for 0) in the each call.
With some memory of C++ syntax I tried this then

{ :one=>1, :two=> 2 }.each &my_lambda

This call gave me a new error, wrong number of parameters (1 for 2) in the block call.
Mmmh so maybe my_lambda need to fulfill a specific signature with one parameter, but what kind of parameter ?
So I tried to investigate it with this:

tell_me_who_you_are_lambda_parameter = lambda{ |arg| puts argarg.class }
{ :one=>1, :two=> 2 }.each &tell_me_who_you_are_lambda_parameter


And so I got the answer:  [:one, 1] Array [:two, 2] Array The parameter is a two element array that contains the key-value pair.
Enough to solve the initial problem, just need to rewrite my_lambda and call it properly like this:

my_lambda = lambda{ |pair| puts pair[0], pair[1] }
{ :one=>1, :two=> 2 }.each &my_lambda


One solution found. Are there more ?


Update: 
Jacopo comments made it clear that the call &my_lambda with 2 arguments work well in 1.8.7.
And Riccardo found and explained me off-line that in 19.3 it do not work because argument passing to blocks, lambdas in this case, has changed and become more strict.
This made it clear to me the source of the problem. Kristoffer suggested off-line to describe the problem with a test, what a great idea! So I did:  http://pastie.org/3149861

Thanks everyone for the precious help



Print | posted @ domenica 8 gennaio 2012 00:11

Comments on this entry:

Gravatar # re: Ruby lambdas and each and enumerators
by riccardo at 08/01/2012 20:19

Visto che commentate in italiano, lo faccio anch'io ;)

Ho fatto un po' di prove e ho visto che anche nella 1.8 alla lambda arriva un array come parametro. Solo che nella 1.8 questo array viene "esploso" in automatico, mentre nella 1.9 no.

Un modo alternativo a quello proposto da te, per risolvere, può essere farlo "a mano":


my_lambda = lambda{ |params| key, value = params, puts key, value }


Ovviamente, nella sostanza, è la stessa cosa.
Comments have been closed on this topic.