The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

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.