Install.pm
Go to the documentation of this file.
1 # Original package Sub::Install downloaded from CPAN on 6/15/2012. This module
2 # has been modified by Andreas Schuh on 6/15/2012 to make it part of BASIS.
3 
4 package BASIS::Sub::Install;
5 
6 use warnings;
7 use strict;
8 
9 use Carp;
10 use Scalar::Util ();
11 
12 =head1 NAME
13 
14 BASIS::Sub::Install - install subroutines into packages easily
15 
16 =head1 VERSION
17 
18 version 0.926
19 
20 =cut
21 
22 our $VERSION = '0.926';
23 
24 =head1 SYNOPSIS
25 
26  use BASIS::Sub::Install;
27 
28  BASIS::Sub::Install::install_sub({
29  code => sub { ... },
30  into => $package,
31  as => $subname
32  });
33 
34 =head1 DESCRIPTION
35 
36 This module makes it easy to install subroutines into packages without the
37 unslightly mess of C<no strict> or typeglobs lying about where just anyone can
38 see them.
39 
40 =head1 FUNCTIONS
41 
42 =head2 install_sub
43 
44  BASIS::Sub::Install::install_sub({
45  code => \&subroutine,
46  into => "Finance::Shady",
47  as => 'launder',
48  });
49 
50 This routine installs a given code reference into a package as a normal
51 subroutine. The above is equivalent to:
52 
53  no strict 'refs';
54  *{"Finance::Shady" . '::' . "launder"} = \&subroutine;
55 
56 If C<into> is not given, the sub is installed into the calling package.
57 
58 If C<code> is not a code reference, it is looked for as an existing sub in the
59 package named in the C<from> parameter. If C<from> is not given, it will look
60 in the calling package.
61 
62 If C<as> is not given, and if C<code> is a name, C<as> will default to C<code>.
63 If C<as> is not given, but if C<code> is a code ref, BASIS::Sub::Install will try to
64 find the name of the given code ref and use that as C<as>.
65 
66 That means that this code:
67 
68  BASIS::Sub::Install::install_sub({
69  code => 'twitch',
70  from => 'Person::InPain',
71  into => 'Person::Teenager',
72  as => 'dance',
73  });
74 
75 is the same as:
76 
77  package Person::Teenager;
78 
79  BASIS::Sub::Install::install_sub({
80  code => Person::InPain->can('twitch'),
81  as => 'dance',
82  });
83 
84 =head2 reinstall_sub
85 
86 This routine behaves exactly like C<L</install_sub>>, but does not emit a
87 warning if warnings are on and the destination is already defined.
88 
89 =cut
90 
91 sub _name_of_code {
92  my ($code) = @_;
93  require B;
94  my $name = B::svref_2object($code)->GV->NAME;
95  return $name unless $name =~ /\A__ANON__/;
96  return;
97 }
98 
99 # See also Params::Util, to which this code was donated.
100 sub _CODELIKE {
101  (Scalar::Util::reftype($_[0])||'') eq 'CODE'
102  || Scalar::Util::blessed($_[0])
103  && (overload::Method($_[0],'&{}') ? $_[0] : undef);
104 }
105 
106 # do the heavy lifting
107 sub _build_public_installer {
108  my ($installer) = @_;
109 
110  sub {
111  my ($arg) = @_;
112  my ($calling_pkg) = caller(0);
113 
114  # I'd rather use ||= but I'm whoring for Devel::Cover.
115  for (qw(into from)) { $arg->{$_} = $calling_pkg unless $arg->{$_} }
116 
117  # This is the only absolutely required argument, in many cases.
118  Carp::croak "named argument 'code' is not optional" unless $arg->{code};
119 
120  if (_CODELIKE($arg->{code})) {
121  $arg->{as} ||= _name_of_code($arg->{code});
122  } else {
123  Carp::croak
124  "couldn't find subroutine named $arg->{code} in package $arg->{from}"
125  unless my $code = $arg->{from}->can($arg->{code});
126 
127  $arg->{as} = $arg->{code} unless $arg->{as};
128  $arg->{code} = $code;
129  }
130 
131  Carp::croak "couldn't determine name under which to install subroutine"
132  unless $arg->{as};
133 
134  $installer->(@$arg{qw(into as code) });
135  }
136 }
137 
138 # do the ugly work
139 
140 my $_misc_warn_re;
141 my $_redef_warn_re;
142 BEGIN {
143  $_misc_warn_re = qr/
144  Prototype\ mismatch:\ sub\ .+? |
145  Constant subroutine \S+ redefined
146  /x;
147  $_redef_warn_re = qr/Subroutine\ \S+\ redefined/x;
148 }
149 
150 my $eow_re;
151 BEGIN { $eow_re = qr/ at .+? line \d+\.\Z/ };
152 
153 sub _do_with_warn {
154  my ($arg) = @_;
155  my $code = delete $arg->{code};
156  my $wants_code = sub {
157  my $code = shift;
158  sub {
159  my $warn = $SIG{__WARN__} ? $SIG{__WARN__} : sub { warn @_ }; ## no critic
160  local $SIG{__WARN__} = sub {
161  my ($error) = @_;
162  for (@{ $arg->{suppress} }) {
163  return if $error =~ $_;
164  }
165  for (@{ $arg->{croak} }) {
166  if (my ($base_error) = $error =~ /\A($_) $eow_re/x) {
167  Carp::croak $base_error;
168  }
169  }
170  for (@{ $arg->{carp} }) {
171  if (my ($base_error) = $error =~ /\A($_) $eow_re/x) {
172  return $warn->(Carp::shortmess $base_error);
173  }
174  }
175  ($arg->{default} || $warn)->($error);
176  };
177  $code->(@_);
178  };
179  };
180  return $wants_code->($code) if $code;
181  return $wants_code;
182 }
183 
184 sub _installer {
185  sub {
186  my ($pkg, $name, $code) = @_;
187  no strict 'refs'; ## no critic ProhibitNoStrict
188  *{"$pkg\::$name"} = $code;
189  return $code;
190  }
191 }
192 
193 BEGIN {
194  *_ignore_warnings = _do_with_warn({
195  carp => [ $_misc_warn_re, $_redef_warn_re ]
196  });
197 
198  *install_sub = _build_public_installer(_ignore_warnings(_installer));
199 
200  *_carp_warnings = _do_with_warn({
201  carp => [ $_misc_warn_re ],
202  suppress => [ $_redef_warn_re ],
203  });
204 
205  *reinstall_sub = _build_public_installer(_carp_warnings(_installer));
206 
207  *_install_fatal = _do_with_warn({
208  code => _installer,
209  croak => [ $_redef_warn_re ],
210  });
211 }
212 
213 =head2 install_installers
214 
215 This routine is provided to allow BASIS::Sub::Install compatibility with
216 BASIS::Sub::Installer. It installs C<install_sub> and C<reinstall_sub> methods into
217 the package named by its argument.
218 
219  BASIS::Sub::Install::install_installers('Code::Builder'); # just for us, please
220  Code::Builder->install_sub({ name => $code_ref });
221 
222  BASIS::Sub::Install::install_installers('UNIVERSAL'); # feeling lucky, punk?
223  Anything::At::All->install_sub({ name => $code_ref });
224 
225 The installed installers are similar, but not identical, to those provided by
226 BASIS::Sub::Installer. They accept a single hash as an argument. The key/value pairs
227 are used as the C<as> and C<code> parameters to the C<install_sub> routine
228 detailed above. The package name on which the method is called is used as the
229 C<into> parameter.
230 
231 Unlike BASIS::Sub::Installer's C<install_sub> will not eval strings into code, but
232 will look for named code in the calling package.
233 
234 =cut
235 
236 sub install_installers {
237  my ($into) = @_;
238 
239  for my $method (qw(install_sub reinstall_sub)) {
240  my $code = sub {
241  my ($package, $subs) = @_;
242  my ($caller) = caller(0);
243  my $return;
244  for (my ($name, $sub) = %$subs) {
245  $return = BASIS::Sub::Install->can($method)->({
246  code => $sub,
247  from => $caller,
248  into => $package,
249  as => $name
250  });
251  }
252  return $return;
253  };
254  install_sub({ code => $code, into => $into, as => $method });
255  }
256 }
257 
258 =head1 EXPORTS
259 
260 BASIS::Sub::Install exports C<install_sub> and C<reinstall_sub> only if they are
261 requested.
262 
263 =head2 exporter
264 
265 BASIS::Sub::Install has a never-exported subroutine called C<exporter>, which is used
266 to implement its C<import> routine. It takes a hashref of named arguments,
267 only one of which is currently recognize: C<exports>. This must be an arrayref
268 of subroutines to offer for export.
269 
270 This routine is mainly for BASIS::Sub::Install's own consumption. Instead, consider
271 L<BASIS::Sub::Exporter>.
272 
273 =cut
274 
275 sub exporter {
276  my ($arg) = @_;
277 
278  my %is_exported = map { $_ => undef } @{ $arg->{exports} };
279 
280  sub {
281  my $class = shift;
282  my $target = caller;
283  for (@_) {
284  Carp::croak "'$_' is not exported by $class" if !exists $is_exported{$_};
285  install_sub({ code => $_, from => $class, into => $target });
286  }
287  }
288 }
289 
290 BEGIN { *import = exporter({ exports => [ qw(install_sub reinstall_sub) ] }); }
291 
292 =head1 SEE ALSO
293 
294 =over
295 
296 =item L<BASIS::Sub::Installer>
297 
298 This module is (obviously) a reaction to Damian Conway's BASIS::Sub::Installer, which
299 does the same thing, but does it by getting its greasy fingers all over
300 UNIVERSAL. I was really happy about the idea of making the installation of
301 coderefs less ugly, but I couldn't bring myself to replace the ugliness of
302 typeglobs and loosened strictures with the ugliness of UNIVERSAL methods.
303 
304 =item L<BASIS::Sub::Exporter>
305 
306 This is a complete Exporter.pm replacement, built atop BASIS::Sub::Install.
307 
308 =back
309 
310 =head1 AUTHOR
311 
312 Ricardo Signes, C<< <rjbs@cpan.org> >>
313 
314 Several of the tests are adapted from tests that shipped with Damian Conway's
315 Sub-Installer distribution.
316 
317 Modified by Andreas Schuh on 6/15/2012 in order to make it a subpackage
318 of the SBIA namespace for inclusion with the BASIS package.
319 
320 =head1 BUGS
321 
322 Please report any bugs or feature requests through the web interface at
323 L<http://rt.cpan.org>. I will be notified, and then you'll automatically be
324 notified of progress on your bug as I make changes.
325 
326 =head1 COPYRIGHT
327 
328 Copyright 2005-2006 Ricardo Signes, All Rights Reserved.
329 
330 This program is free software; you can redistribute it and/or modify it
331 under the same terms as Perl itself.
332 
333 =cut
334 
335 1;