File Coverage

blib/lib/Sub/AliasedUnderscore.pm
Criterion Covered Total %
statement 15 15 100.0
branch n/a
condition n/a
subroutine 6 6 100.0
pod 2 2 100.0
total 23 23 100.0


line stmt bran cond sub pod time code
1             package Sub::AliasedUnderscore;
2 2     2   47876 use strict;
  2         6  
  2         64  
3 2     2   11 use warnings;
  2         3  
  2         88  
4              
5             our $VERSION = 0.02;
6              
7 2     2   11 use base 'Exporter';
  2         14  
  2         562  
8              
9             our @EXPORT = ();
10             our @EXPORT_OK = qw/transform transformed/;
11             our %EXPORT_TAGS = ( all => \@EXPORT_OK );
12              
13             =head1 NAME
14              
15             Sub::AliasedUnderscore - transform a subroutine that operates on C<$_> into
16             one that operates on C<$_[0]>
17              
18             =head1 SYNOPSIS
19              
20             use Sub::AliasedUnderscore qw/transform transformed/;
21              
22             my $increment = sub { $_++ };
23             $increment = transform $increment;
24              
25             $_ = 1;
26              
27             my $a = 41;
28             $increment->($a); # returns 41
29             # $a is now 42; $_ is still 1
30              
31             my $decrement = transformed { $_-- };
32             $decrement->($a);
33             # $a is now 41; $_ is still 1
34              
35             =head1 DESCRIPTION
36              
37             Often you'll want to accept a subroutine that operates on C<$_>, like
38             C and C do. The details of getting C<$_> to work that way
39             are inconvenient to worry about every time, so this module abstracts
40             that away. Transform the subroutine that touches C<$_> with C,
41             and then treat it as though it is operating on C<$_[0]>.
42              
43             =head1 EXPORT
44              
45             Nothing by default. If you want C or C,
46             request them in the import list.
47              
48             =head1 FUNCTIONS
49              
50             =head2 transform($sub)
51              
52             Transforms $sub to modify C<$_[0]> instead of C<$_>.
53              
54             This means you can write your subroutine as though it were the first
55             argument of C or C, but execute it like C<$sub->($arg)>.
56              
57             Everything works exactly the same as C or C -- C<$_> is
58             localized, but aliased to whatever you call the subroutine with. That
59             means that modifying C<$_> in C<$sub> will modify the argument passed
60             to the transformed sub, but won't touch the $_ that already exists.
61              
62             It makes C<$_> DWIM.
63              
64             =cut
65              
66             sub transform($) {
67 2     2 1 12 my $sub = shift;
68             return sub {
69 2     2   8 local *_ = \$_[0];
70 2         6 $sub->();
71             }
72 2         10 }
73              
74             =head2 transformed BLOCK
75              
76             Like C, but accepts a code block instead of a coderef:
77              
78             my $sub = transformed { do something to $_ }
79             $sub->($a); # $a is $_ in the above block
80              
81             =cut
82            
83             sub transformed(&) {
84 1     1 1 1925 my $sub = shift;
85 1         4 return transform($sub);
86             }
87              
88             =head1 BUGS
89              
90             None known; report to RT.
91              
92             =head1 CODE
93              
94             The repository is managed by git. You can clone the repository with:
95              
96             git clone git://git.jrock.us/Sub-AliasedUnderscore
97              
98             Patches welcome!
99              
100             =head1 AUTHOR
101              
102             Jonathan Rockway C<< jrockway@cpan.org >>
103              
104             =head1 LICENSE
105              
106             Copyright (c) 2007 Jonathan Rockway. You may use, modify, and
107             distribute this code under the same conditions as Perl itself.
108              
109             =cut
110              
111             1;