File Coverage

blib/lib/Sub/Exporter/ForMethods.pm
Criterion Covered Total %
statement 33 37 89.1
branch 3 4 75.0
condition 2 3 66.6
subroutine 13 15 86.6
pod 1 2 50.0
total 52 61 85.2


line stmt bran cond sub pod time code
1 2     2   133763 use strict;
  2         16  
  2         46  
2 2     2   8 use warnings;
  2         3  
  2         78  
3             package Sub::Exporter::ForMethods 0.100055;
4             # ABSTRACT: helper routines for using Sub::Exporter to build methods
5              
6 2     2   9 use Scalar::Util ();
  2         4  
  2         41  
7 2     2   358 use Sub::Util ();
  2         308  
  2         66  
8              
9 2         13 use Sub::Exporter 0.978 -setup => {
10             exports => [ qw(method_installer method_goto_installer) ],
11 2     2   1063 };
  2         25443  
12              
13             #pod =head1 SYNOPSIS
14             #pod
15             #pod In an exporting library:
16             #pod
17             #pod package Method::Builder;
18             #pod
19             #pod use Sub::Exporter::ForMethods qw(method_installer);
20             #pod
21             #pod use Sub::Exporter -setup => {
22             #pod exports => [ method => \'_method_generator' ],
23             #pod installer => method_installer,
24             #pod };
25             #pod
26             #pod sub _method_generator {
27             #pod my ($self, $name, $arg, $col) = @_;
28             #pod return sub { ... };
29             #pod };
30             #pod
31             #pod In an importing library:
32             #pod
33             #pod package Vehicle::Autobot;
34             #pod use Method::Builder method => { -as => 'transform' };
35             #pod
36             #pod =head1 DESCRIPTION
37             #pod
38             #pod The synopsis section, above, looks almost indistinguishable from any other
39             #pod use of L, apart from the use of
40             #pod C. It is nearly indistinguishable in behavior, too. The
41             #pod only change is that subroutines exported from Method::Builder into named slots
42             #pod in Vehicle::Autobot will be wrapped in a subroutine called
43             #pod C. This will insert a named frame into stack
44             #pod traces to aid in debugging.
45             #pod
46             #pod More importantly (for the author, anyway), they will not be removed by
47             #pod L. This makes the following code
48             #pod work:
49             #pod
50             #pod package MyLibrary;
51             #pod
52             #pod use Math::Trig qw(tan); # uses Exporter.pm
53             #pod use String::Truncate qw(trunc); # uses Sub::Exporter's defaults
54             #pod
55             #pod use Sub::Exporter::ForMethods qw(method_installer);
56             #pod use Mixin::Linewise { installer => method_installer }, qw(read_file);
57             #pod
58             #pod use namespace::autoclean;
59             #pod
60             #pod ...
61             #pod
62             #pod 1;
63             #pod
64             #pod After MyLibrary is compiled, C will remove C and
65             #pod C as foreign contaminants, but will leave C in place. It
66             #pod will also remove C, an added win.
67             #pod
68             #pod =head1 EXPORTS
69             #pod
70             #pod Sub::Exporter::ForMethods offers only one routine for export, and it may also
71             #pod be called by its full package name:
72             #pod
73             #pod =head2 method_installer
74             #pod
75             #pod my $installer = method_installer(\%arg);
76             #pod
77             #pod This routine returns an installer suitable for use as the C argument
78             #pod to Sub::Exporter. It updates the C<\@to_export> argument to wrap all code that
79             #pod will be installed by name in a named subroutine, then passes control to the
80             #pod default Sub::Exporter installer.
81             #pod
82             #pod The only argument to C is an optional hashref which may
83             #pod contain a single entry for C. If the value for C is true,
84             #pod when a blessed subroutine is wrapped, the wrapper will be blessed into the same
85             #pod package.
86             #pod
87             #pod =cut
88              
89             sub method_installer {
90             _generic_method_installer(
91 6     6   9 sub { my $code = shift; sub { $code->(@_) } },
  6     4   15  
  4     4   2578  
        2      
        2      
92 3     3 1 873 @_,
93             );
94             }
95              
96             sub method_goto_installer {
97             _generic_method_installer(
98 0     0   0 sub { my $code = shift; sub { goto &$code } },
  0         0  
  0         0  
99 0     0 0 0 @_,
100             );
101             }
102              
103             sub _generic_method_installer {
104 3     3   7 my $generator = shift;
105              
106 3         6 my ($mxi_arg) = @_;
107 3         6 my $rebless = $mxi_arg->{rebless};
108              
109             sub {
110 3     3   1360 my ($arg, $to_export) = @_;
111              
112 3         5 my $into = $arg->{into};
113              
114 3         10 for (my $i = 0; $i < @$to_export; $i += 2) {
115 6         13 my ($as, $code) = @$to_export[ $i, $i+1 ];
116              
117 6 50       15 next if ref $as;
118 6         14 my $sub = $generator->($code);
119 6 100 66     29 if ($rebless and defined (my $code_pkg = Scalar::Util::blessed($code))) {
120 1         4 bless $sub, $code_pkg;
121             }
122              
123 6         46 $to_export->[ $i + 1 ] = Sub::Util::set_subname(
124             join(q{::}, $into, $as),
125             $sub,
126             );
127             }
128              
129 3         9 Sub::Exporter::default_installer($arg, $to_export);
130 3         19 };
131             }
132              
133             1;
134              
135             __END__