N
nvp
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,<second_arg>|, 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?
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,<second_arg>|, 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?