File Coverage

blib/lib/AutoCurry.pm
Criterion Covered Total %
statement 42 42 100.0
branch 6 8 75.0
condition 3 6 50.0
subroutine 15 15 100.0
pod 2 6 33.3
total 68 77 88.3


line stmt bran cond sub pod time code
1             package AutoCurry;
2              
3             # Tom Moertel
4             # 2005-02-17
5              
6             =head1 NAME
7              
8             AutoCurry - automatically create currying variants of functions
9              
10             =head1 SYNOPSIS
11              
12             use AutoCurry qw( foo ); # pass :all to curry all functions
13              
14             sub foo { print "@_\n"; }
15             # currying variant, foo_c, is created automatically
16              
17             my $hello = foo_c("Hello, ");
18             $hello->("world!"); # Hello, world!
19             $hello->("Pittsburgh!"); # Hello, Pittsburgh!
20              
21             =cut
22              
23 2     2   42023 use Carp;
  2         5  
  2         257  
24              
25 2     2   10 use warnings;
  2         3  
  2         43  
26 2     2   9 use strict;
  2         7  
  2         587  
27              
28             our $VERSION = "0.1003";
29             our $suffix = "_c";
30              
31             my $PKG = __PACKAGE__;
32              
33 10 50   10   39 sub _debug { print STDERR "AutoCurry: @_\n" if $ENV{AUTOCURRY_DEBUG} }
34              
35             sub curry {
36 19     19 0 28 my $f = shift;
37 19         29 my $args = \@_;
38 19     18   106 sub { $f->(@$args, @_) };
  18         1573  
39             }
40              
41             sub curry_package {
42 4   66 4 1 662 my $pkg = shift || caller;
43 4         13 curry_named_functions_from_package( $pkg,
44             get_function_names_from_package( $pkg )
45             );
46             }
47              
48             sub curry_named_functions {
49 4     4 1 616 return curry_named_functions_from_package( scalar caller(), @_ );
50             }
51              
52             sub curry_named_functions_from_package {
53 2     2   11 no strict 'refs';
  2         4  
  2         359  
54 11     11 0 25 my $pkg = shift() . "::";
55 10         19 map {
56 10 100       47 my $curried_name = $_ . $suffix;
57 10 50       36 carp "$PKG: currying $_ over existing $curried_name"
58             if *$curried_name{CODE};
59 10         27 _debug("making $curried_name");
60 10         37 *$curried_name = curry( \&curry, \&$_ );
61 10         95 $curried_name;
62 11         3680 } map { /::/ ? $_ : "$pkg$_" } @_;
63             }
64              
65             sub get_function_names_from_package {
66 2     2   13 no strict 'refs';
  2         3  
  2         546  
67 4   33 4 0 16 my $pkg = shift || caller;
68 4         8 my $symtab = *{ $pkg . "::" }{HASH};
  4         16  
69 4         86 sort grep *$_{CODE}, # drop symbols w/o code
70             map $pkg."::$_", # fully qualify
71             grep !/^_|^[_A-Z]+$/, # drop _underscored & ALL_CAPS
72             keys %$symtab; # get all symbols for package
73             }
74              
75             my @init;
76              
77             sub import {
78 3     3   15 shift; # don't need self
79 3         4 my $caller = caller;
80 3 100       15 push @init, curry_package_c($caller) if grep /^:all$/, @_;
81 3         11 curry_named_functions_from_package($caller, grep !/^:/, @_);
82             }
83              
84 2     2   9 INIT { finish_initialization() }
85              
86             sub finish_initialization {
87 2     2 0 11 $_->() for @init; @init = ();
  2         13  
88             }
89              
90             # physician, curry thyself!
91              
92             curry_named_functions(qw(
93             curry_package
94             ));
95              
96              
97             1;
98              
99             __END__