NAME
Sub::Curry::Cookbook
DESCRIPTION
This is the cookbook for Sub::Curry.
GOOD THINGS TO KNOW
$self->$subref(...)
This is valid Perl and calls
$subref
directly without looking at$self
. I.e. it does$subref->($self, ...)
. See "The Arrow Operator" in perlop.$self->can($method)
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.
RECIPES
Right-curring
Problem: You want to right-curry a function.
Solution: See "Add trailing spice" elsewhere in this cookbook.
Name a curried subroutine
Problem: You want to use a curried subroutine like a named function or method.
Solution:
*name = $curried;
or directly
*name = curry(...);
See "Typeglobs and Filehandles" in perldata.
You may want to use Sub::Name if your source subroutine is anonymous.
Convert function to method
Problem: You want to call a function as a method
Solution:
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.
Convert method to function
Problem: You want to use a method like a plain function.
Solution:
my $method = 'foo';
my $func = curry($self->can($method), $self);
$func->(@args);
Discussion: $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 $self
.
Curry a method
Problem: You want a method to be curried.
Solution:
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.
Add spice after a hole in a curried subroutine.
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.
Add trailing spice
Problem: You want to add spice to the end of the argument list where the argument list is of unknown length.
Solution:
my $curried = curry($func, @spice, BLACKHOLE, @trailing_spice);
Discussion: Nothing special here, just a demonstration of how a blackhole works.
Add trailing spice to a curried subroutine with a blackhole in it.
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.
Append spice without it being processed at all.
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.
Solution:
my $curried2 = curry(
$curried->uncurried,
$curried->spice,
@spice
);
or
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.
AUTHOR
Johan Lodin <lodin@cpan.org>
COPYRIGHT
Copyright 2004 Johan Lodin. All rights reserved.