- GOOD THINGS TO KNOW
This is the cookbook for Sub::Curry.
This is valid Perl and calls
$subrefdirectly without looking at
$self. I.e. it does
$subref->($self, ...). See "The Arrow Operator" in perlop.
UNIVERSAL::can()returns a code reference if used as a method and the method named as first argument was found. See "Default UNIVERSAL methods" in perlobj.
Problem: You want to right-curry a function.
Solution: See "Add trailing spice" elsewhere in this cookbook.
Problem: You want to use a curried subroutine like a named function or method.
*name = $curried;
*name = curry(...);
You may want to use Sub::Name if your source subroutine is anonymous.
Problem: You want to call a function as a method
my $func = \&foo; my $method = curry($func, ANTISPICE); $self->$method(@args);
Discussion: The antispice removes the callee, i.e. the LHS of the arrow operator, making it work just like a function call.
Problem: You want to use a method like a plain function.
my $method = 'foo'; my $func = curry($self->can($method), $self); $func->(@args);
$func now has
$self as first object argument. This is handy when wanting to have methods in dispatch tables. Be aware though that the same object will be used when
$func->() is called, even if
$self is another object later.
Note that the second argument to
&curry can be anything and not necessarily
Problem: You want a method to be curried.
my $method = 'foo'; my $curried_method = curry($self->can($method), HOLE, @spice); $self->$curried_method(@args);
Discussion: This just leaves a hole for the object.
Problem: You have a hole in your curried subroutine but want to add more spices after or fill out holes after your first hole.
Solution: Assuming no special spice before the first hole:
my $curried2 = $curried->new(HOLE, @spice);
Discussion: You simply put a hole in the hole. There's not much to it.
Problem: You want to add spice to the end of the argument list where the argument list is of unknown length.
my $curried = curry($func, @spice, BLACKHOLE, @trailing_spice);
Discussion: Nothing special here, just a demonstration of how a blackhole works.
Problem: You have a curried subroutine that you want to spice up some more and place the spice at the end. The problem is that there's a blackhole that slurps the spice placing where it's not intended. You still want the blackhole to exist after you added the new spice.
Solution: Assuming there's no special spice in
$curried before the blackhole:
my $curried2 = $curried->new(BLACKHOLE, WHITEHOLE, @spice);
Discussion: This is similar to "Add spice after a hole". By giving the blackhole another blackhole, you have two successive blackholes, the first newly added and the second the one that added the new. The whitehole is then removes the second blackhole -- the blackhole doing the inserting. The spice is then added like usual, yet a blackhole exists at the right place.
Problem: You have a curried subroutine in
$curried that may have special spices in it. You want to add more spices. You do not want the new spice to be processed as an application on the old spice. You just want to append more spice.
my $curried2 = curry( $curried->uncurried, $curried->spice, @spice );
my $curried2 = Sub::Curry::->new( $curried->uncurried, $curried->spice, @spice );
Discussion: Since new spice will be processed if you try to use the second form of
&new you need to manually pull out the original subroutine and the applied spice. Then you curry the original subroutine but with the new spice added to the spice list.
Johan Lodin <email@example.com>
Copyright 2004 Johan Lodin. All rights reserved.