Rob Kinyon > Sub-Compose-0.01 > Sub::Compose

Download:
Sub-Compose-0.01.tar.gz

Dependencies

Annotate this POD

View/Report Bugs
Module Version: 0.01   Source  

NAME ^

Sub::Compose

SYNOPSIS ^

  use Sub::Compose qw( compose );

  sub factory {
      my ($mult) = @_;
      return sub {
          my $val = shift;
          return $val * $mult;
      }
  }

  my $times_two = factory( 2 );
  my $times_three = factory( 3 );

  my $times_six = compose( $times_two, $times_three );

  $times_six->( 4 ); # 24

DESCRIPTION ^

The compose() function takes any number of subroutine references and creates a new subroutine reference from them that

RATIONALE ^

I like creating little subroutines that do interesting bits of work. I then like to build other subroutines by calling these guys and so on and so forth. Sometimes, I build up subroutines with calls 3 and 4 levels deep. This causes two problems:

While I could pass little strings around and eventually eval them, I don't think that way - I think in terms of little pieces of work that I can put together like Tinkertoys(TM) or Legos(TM).

Also, strings don't close over variables. Most of the functions I use in this way are closures, so that method doesn't even work.

METHODOLOGY ^

Currently, this uses Data::Dump::Streamer to deparse the subroutines along with their lexical environments and then intelligently concatenates the output to form a single subroutine. As such, it has all issues that DDS has in terms of parsing coderefs. Please refer to that documentation for more details.

I am working on revamping this so that I manipulate the opcodes directly vs. deparsing. This should have increased performance and, hopefully, will reduce the likelihood of any edge cases. As this is my first foray into the world of perlguts, we'll see how it goes. :-)

FUNCTIONS ^

chain()

This is the old style of doing this and is provided for reference. It is implemented as so:

  sub chain {
      my (@subs) = @_;

      return subname chainer => sub {
          foreach my $sub ( @subs ) {
              @_ = $sub->( @_ );
          }

          return @_;
      };
  }

As you can see, if there's a good 10-15 subroutines involved, this can be a lot of extra work, particularly if the subroutines are very small.

compose()

This is what this module is all about. Create a single subroutine from a bunch of subroutines that were passed in while still preserving closures.

BUGS ^

I'm sure this code has bugs somewhere. If you find one, please email me a failing test and I'll make it pass in the next release.

CODE COVERAGE ^

We use Devel::Cover to test the code coverage of our tests. Below is the Devel::Cover report on this module's test suite.

  ---------------------------- ------ ------ ------ ------ ------ ------ ------
  File                           stmt   bran   cond    sub    pod   time  total
  ---------------------------- ------ ------ ------ ------ ------ ------ ------
  blib/lib/Sub/Compose.pm       100.0   92.9    n/a  100.0  100.0  100.0   99.0
  Total                         100.0   92.9    n/a  100.0  100.0  100.0   99.0
  ---------------------------- ------ ------ ------ ------ ------ ------ ------

AUTHORS ^

Rob Kinyon <rob.kinyon@iinteractive.com>

Stevan Little <stevan.little@iinteractive.com>

Thanks to Infinity Interactive for generously donating our time.

COPYRIGHT AND LICENSE ^

Copyright 2005 by Infinity Interactive, Inc.

http://www.iinteractive.com

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

syntax highlighting: