From: "David A. Black" Date: 2008-10-29T02:36:26+09:00 Subject: Re: lambda and multiple arguments: how?! Hi -- On Wed, 29 Oct 2008, nvp wrote: > Hello, > > I've been working on porting a useful Perl module to Ruby and have > been struggling with the differences between Perl's function > references and Ruby's lambda, proc, etc. > > Basically, my Perl module has two functions that do this: > > sub run_on_finish { my ($s,$code,$pid)=@_; > $s->{on_finish}->{$pid || 0}=$code; > } > > sub on_finish { my ($s,$pid,@par)=@_; > my $code=$s->{on_finish}->{$pid} || $s->{on_finish}->{0} or return 0; > $code->($pid,@par); > }; > > Using the above, I can do the following: > > $obj->run_on_finish(sub { my($pid, $exit_code, $ident) = @_; > # Do something with $pid, $exit_code, $ident > }); > > In Ruby, things are more difficult given that I don't fully understand > closures yet. I've reimplemented the methods like so: > > # module > def run_on_finish(code, pid=0) > begin > self.do_on_finish[pid] = code > rescue > raise "error in run_on_finish\n" # Message stinks > end > end > > def on_finish(pid, *params) > code = self.do_on_finish[pid] || self.do_on_finish[0] or return 0 > begin > code.call(pid, params) > rescue > raise "lameness\n" # Message stinks > end > end > > # client > pfm.run_on_finish( > lambda { > |pid,exit_code,ident| > print "LEN ", pid.length(), " -- ", "MY ARGS ", pid.join(':'), "\n" > } > ) > > As you can see, I'm calling self.do_on_finish with the arguments > 'pid', and an array of 'params'. > Unfortunately Ruby only matches |pid,|, and this is not > the behavior I'd expect or > want. > > Outside of setting |*params| in lambda {} such that I would check/set > my values manually, is > there a way to provide lambda with more than two arguments? You could call it as: code.call(pid,*params), or maybe try this technique: func = lambda {|a,(b,c)| p a,b,c } func.call(1,[2,3]) The (b,c) notation will cause the array to be spread over those two parameters. David -- Rails training from David A. Black and Ruby Power and Light: Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL Advancing with Rails January 19-22 Fort Lauderdale, FL * * Co-taught with Patrick Ewing! See http://www.rubypal.com for details and updates!