File Coverage

blib/lib/namespace/local.pm
Criterion Covered Total %
statement 218 219 99.5
branch 64 72 88.8
condition 37 54 68.5
subroutine 40 40 100.0
pod 1 1 100.0
total 360 386 93.2


line stmt bran cond sub pod time code
1 15     15   803323 use 5.008;
  15     8   159  
  8         550620  
  8         94  
2 15     15   82 use strict;
  15     8   34  
  15         484  
  8         42  
  8         14  
  8         275  
3 15     15   84 use warnings FATAL => 'all';
  15     8   29  
  15         1359  
  8         50  
  8         21  
  8         788  
4              
5             package namespace::local;
6              
7             our $VERSION = '0.08';
8              
9             =head1 NAME
10              
11             namespace::local - Confine imports or functions to a given scope
12              
13             =head1 SYNOPSIS
14              
15             This module allows to confine imports or private functions
16             to a given scope.
17              
18             package My::Module;
19              
20             sub normal_method {
21             # frobnicate; # nope!
22             };
23              
24             sub method_with_sugar {
25             use namespace::local;
26             use Crazy::Prototyped::DSL qw(do_this do_that frobnicate);
27              
28             do_this;
29             do_that;
30             frobnicate;
31             };
32              
33             sub another_method {
34             # frobnicate; # nope!
35             };
36              
37             The calling module's symbol table is saved at the C line
38             and restored upon leaving the block.
39              
40             The subsequent imports will do their job within the block,
41             but will not be available as methods at runtime.
42              
43             =head1 MODES OF OPERATION
44              
45             =head2 -around
46              
47             This confines all subsequent imports and functions
48             between the use of L and the end of scope.
49              
50             package My::Package;
51              
52             sub normal_sub {
53             # frobnicate() is unknown
54             }
55              
56             sub using_import {
57             use namespace::local -around;
58             use Some::Crazy::DSL qw(frobnicate);
59             frobnicate Foo => 42;
60             }
61              
62             sub no_import {
63             # frobnicate() is unknown
64             }
65              
66             =head2 -below (the default)
67              
68             Hides subsequent imports and functions on end of scope.
69              
70             This may be used to mask private functions:
71              
72             package My::Package;
73             use Moo::Role;
74              
75             # This is available everywhere
76             sub public {
77             return private();
78             };
79              
80             use namespace::local -below;
81              
82             # This is only available in the current file
83             sub private {
84             return 42;
85             };
86              
87             Note that this doesn't work for private I since methods
88             are resolved at runtime.
89              
90             =head2 -above
91              
92             Hide all functions and exports above the use line.
93              
94             This emulates L, by which this module is clearly inspired.
95              
96             package My::Module;
97             use POSIX;
98             use Time::HiRes;
99             use Carp;
100             use namespace::local -above;
101              
102             # now define public functions here
103              
104             =head1 OPTIONS
105              
106             Extra options may be passed to namespace::local:
107              
108             =head2 -target => Package::Name
109              
110             Act on another package instead of the caller.
111             Note that L is only meant to be used in BEGIN phase.
112              
113             =head2 -except => \@list
114              
115             Exempt symbols mentioned in list (with sigils)
116             from the module's action.
117              
118             No sigil means a function.
119             Only names made of word characters are supported.
120              
121             =head2 -except =>
122              
123             Exempt symbols with names matching the regular expression
124             from the module's action.
125              
126             Note that sigils are ignored here.
127              
128             =head2 -only => \@list
129              
130             Only affect the listed symbols (with sigils).
131             Rules are the same as for -except.
132              
133             =head2 -only =>
134              
135             Only affect symbols with matching names.
136              
137             All C<-only> and C<-except> options act together, further restricting the
138             set of affected symbols.
139              
140             =head1 EXEMPTIONS
141              
142             The following symbols are not touched by this module, to avoid breaking things:
143              
144             =over
145              
146             =item * anything that does not consist of word characters;
147              
148             =item * $_, @_, $1, $2, ...;
149              
150             =item * Arrays: C<@CARP_NOT>, C<@EXPORT>, C<@EXPORT_OK>, C<@ISA>;
151              
152             =item * Hashes: C<%OVERLOAD>;
153              
154             =item * Files: C, C, C, C;
155              
156             =item * Functions: C, C, C;
157              
158             =item * Scalars: C<$AUTOLOAD>, C<$a>, C<$b>;
159              
160             =back
161              
162             This list is likely incomplete, and may grow in the future.
163              
164             =head1 METHODS/FUNCTIONS
165              
166             None.
167              
168             =head1 CAVEATS
169              
170             This module is highly experimental.
171             The following two conditions are guaranteed to hold
172             at least until leaving the beta stage:
173              
174             =over
175              
176             =item * All symbols available before the use line will stay so
177             after end of scope
178              
179             =item * All I imported I below the use line
180             with names consisting of words and not present in L
181             are not going to be available after end of scope.
182              
183             =back
184              
185             The rest is a big grey zone.
186              
187             Currently the module works by saving and then restoring globs,
188             so variables and filehandles are also reset.
189             This may be changed in the future.
190              
191             Due to order of callback execution in L,
192             other modules in C namespace may interact poorly
193             with L.
194              
195             Up to v.0.07, C<-around> used to be the default mode instead of C<-below>.
196             C<-around> is much more restrictive, in particular, it prevents functions
197             defined below the block from propagating above the block.
198              
199             This is less of a problem than imported functions leaking upward.
200             No perfect solution has yet been found.
201              
202             =cut
203              
204 23     23   10266 use B::Hooks::EndOfScope 'on_scope_end';
  23         249556  
  23         155  
205              
206             my @stack;
207              
208             sub import {
209 29     29   1856 my $class = shift;
210              
211 29         119 my $command = namespace::local::_command->new( caller => [ caller ] );
212 29         113 $command->parse_options( @_ );
213              
214             # on_scope_end executes multiple callbacks as FIFO
215             # we need reversed order, so use a stack of commands.
216 25 100       104 $stack[-1]->set_next( $command ) if @stack;
217 25         116 push @stack, $command;
218              
219 25         119 $command->prepare;
220              
221             on_scope_end {
222 25     25   1863 local $Carp::Internal{'B::Hooks::EndOfScope::XS'} = 1;
223 25         57 local $Carp::Internal{'B::Hooks::EndOfScope'} = 1;
224 25         47 pop @stack;
225 25         75 $command->execute;
226 25         134 };
227             };
228              
229             =head1 ENVIRONMENT
230              
231             Set C to see some debugging information
232             upon module load.
233              
234             =head1 THE INTERNALS
235              
236             A stack of "command" objects is used behind the scenes.
237              
238             Its interface is not public, see this module's source.
239              
240             Calling
241              
242             =over
243              
244             =item new
245              
246             =back
247              
248             on this package will create a command object,
249             I a C instance.
250              
251             The creation and destruction of command has no effect on the namespaces.
252              
253             Instead, special C and C methods
254             are called upon import and leaving scope, respectively.
255              
256             =cut
257              
258             sub new {
259 1     1 1 12 my $unused = shift;
260 1         4 namespace::local::_command->new(caller => [caller 0], @_);
261             };
262              
263             package
264             namespace::local::_command;
265              
266             # FIRST AND FOREMOST
267              
268             # See C for how perl stores the Symbol Tables.
269              
270             # In this module we use two-level hashrefs to represent the table:
271             # $table->{ $name }{ $type } = $reference
272             # where $name is a function/variable/whatever name,
273             # $type is one of ARRAY, CODE, FORMAT, HASH, IO, and SCALAR (see @TYPES below),
274             # and $reference is a reference of corresponding type (or undef).
275              
276             # So Foo::bar() would be represented as $table->{foo}{CODE}
277             # whereas @Foo::ISA is $table->{ISA}{ARRAY}.
278              
279 23     23   5923 use Carp;
  23         52  
  23         1245  
280 23     23   142 use Scalar::Util qw(blessed refaddr reftype);
  23         41  
  23         1841  
281             our @CARP_NOT = qw(namespace::local);
282              
283             # TODO need better env parsing...
284 23 100 100 23   143 use constant DEBUG => ( lc ($ENV{PERL_NAMESPACE_LOCAL} || '' ) eq 'debug' ? 1 : 0 );
  23         43  
  23         44234  
285              
286             ### Setup methods
287              
288             sub new {
289 30     30   566 my ($class, %opt) = @_;
290              
291             # TODO check options
292 30   50     143 $opt{caller} ||= [ caller 0 ];
293 30   33     241 $opt{except_rex} ||= qr/^[0-9]+$|^_$/; # no matter what, exempt $_, $1, ...
294 30   33     180 $opt{only_rex} ||= qr/^/; # match all
295 30   50     156 $opt{action} ||= '-below';
296 30   66     141 $opt{target} ||= $opt{caller}[0];
297 30   33     121 $opt{origin} ||= join ":", @{$opt{caller}}[1,2];
  30         167  
298              
299             # Skip some well-known variables and functions
300             # Format: touch_not{ $name }{ $type }
301             # NOTE if you change the list, also change the EXEMPTIONS section in the POD.
302 30         201 $opt{touch_not}{$_}{ARRAY}++ for qw( CARP_NOT EXPORT EXPORT_OK ISA );
303 30         143 $opt{touch_not}{$_}{CODE}++ for qw( AUTOLOAD DESTROY import );
304 30         102 $opt{touch_not}{$_}{HASH}++ for qw( OVERLOAD );
305 30         152 $opt{touch_not}{$_}{IO}++ for qw( DATA STDERR STDIN STDOUT );
306 30         117 $opt{touch_not}{$_}{SCALAR}++ for qw( AUTOLOAD a b );
307              
308 30         91 return bless \%opt, $class;
309             };
310              
311             sub set_next {
312 5     5   11 my ($self, $next) = @_;
313              
314             carp "probably a bug in namespace::local - uncommitted command replaced in chain"
315 5 50 66     22 if $self->{next} and !$self->{next}{done};
316              
317 5         10 $self->{next} = $next;
318             };
319              
320             sub DESTROY {
321 5     5   4344 my $self = shift;
322             carp "probably a bug in namespace::local: callback set at $self->{origin} but never executed"
323 5 50 33     201 if $self->{todo} and !$self->{done};
324             };
325              
326             my %known_action;
327             $known_action{$_}++ for qw(-above -below -around);
328              
329             # This changes nothing except the object itself
330             # input is the same as that of namespace::local->import
331             sub parse_options {
332 29     29   46 my $self = shift;
333              
334             # wrote a Getopt::Long from scratch...
335 29         94 while (@_) {
336 27         51 my $arg = shift;
337 27 100       112 if ( $known_action{$arg} ) {
    100          
    100          
    100          
338 15         102 $self->{action} = $arg;
339             } elsif ($arg eq '-target') {
340 2         11 $self->{target} = shift;
341             } elsif ($arg eq '-except') {
342 5         9 my $cond = shift;
343 5 100       26 if (ref $cond eq 'Regexp') {
    100          
344 1         38 $self->{except_rex} = qr((?:$self->{except_rex})|(?:$cond));
345             } elsif (ref $cond eq 'ARRAY') {
346 3         21 $self->touch_not( @$cond );
347             } else {
348 1         3 _croak( "-except argument must be regexp or array" )
349             };
350             } elsif ($arg eq '-only') {
351 4         8 my $cond = shift;
352 4 100       19 if (ref $cond eq 'Regexp') {
    100          
353 2         24 $self->{only_rex} = $cond;
354             } elsif (ref $cond eq 'ARRAY') {
355 1         9 $self->restrict( @$cond );
356             } else {
357 1         3 _croak( "-only argument must be regexp or array" )
358             };
359             } else {
360 1         4 _croak( "unknown option $arg" );
361             };
362             };
363             };
364              
365             sub touch_not {
366 3     3   12 my ($self, @list) = @_;
367              
368 3         9 foreach (sigil_to_type(@list)) {
369 3         24 $self->{touch_not}{ $_->[0] }{ $_->[1] }++
370             };
371             };
372              
373             sub restrict {
374 1     1   7 my ($self, @list) = @_;
375              
376 1         2 foreach (sigil_to_type(@list)) {
377 2         25 $self->{restrict_symbols}{ $_->[0] }{ $_->[1] }++
378             };
379             };
380              
381             # TODO join with @TYPES array from below
382             my %sigil = (
383             '' => 'CODE',
384             '$' => 'SCALAR',
385             '%' => 'HASH',
386             '@' => 'ARRAY',
387             );
388              
389             # returns [ name, type ] for each argument
390             sub sigil_to_type {
391             map {
392 4 100   4   10 /^([\$\@\%]?)(\w+)$/
  6         44  
393             or _croak( "cannot exempt sybmol $_: unsupported format" );
394 5         29 [ $2, $sigil{$1} ]
395             } @_;
396             };
397              
398             ### Command pattern split into prepare + execute
399              
400             # input: none
401             # output: none
402             # side effects: modify target package + setup callback for self->execute
403             sub prepare {
404 25     25   46 my $self = shift;
405              
406 25         85 my $action = $self->{action};
407              
408 25         77 my $table = $self->read_symbols;
409              
410 25 100       102 if ($action eq '-around') {
    100          
411             # Overwrite symbol table with a copy of itself.
412             # Somehow this triggers binding of symbols in the code
413             # that was parsed so far (i.e. above the 'use' line)
414             # and undefined symbols (in that area) remain so forever
415 4         13 $self->write_symbols( $table );
416             } elsif ( $action eq '-below' ) {
417             # Stabilize known functions, leave everything else as is
418 14         42 my $func = $self->filter_functions( $table );
419 14         38 $self->write_symbols( $func );
420             };
421              
422 25 100       82 if ($action eq '-above' ) {
423             $self->{todo} = sub {
424 7     7   18 $self->erase_only_symbols( $table );
425 7         36 };
426             } else {
427             $self->{todo} = sub {
428 18     18   46 $self->replace_symbols( undef, $table );
429 18         104 };
430             };
431             };
432              
433             # input: none
434             # output: none
435             # side effect: modify target package
436             sub execute {
437 28     28   60 my ($self) = @_;
438              
439             # always execute stacked commands in reverse order
440             $self->{next}->execute
441 28 100       91 if $self->{next};
442              
443             $self->{todo}->()
444 28 100       132 unless $self->{done}++;
445             };
446              
447             ### High-level effectful functions
448              
449             # Don't ever touch NAME, PACKAGE, and GLOB that are also known to Perl
450             my @TYPES = qw(SCALAR ARRAY HASH CODE IO FORMAT);
451              
452             # In: symbol table hashref
453             # Out: side effect
454             sub erase_only_symbols {
455 7     7   15 my ($self, $table) = @_;
456              
457 7         15 my $package = $self->{target};
458 7         23 my @list = keys %$table;
459              
460             # load all necessary symbols
461 7         21 my $current = $self->read_symbols( \@list );
462              
463             # filter out what we were going to delete
464 7         16 foreach my $name ( @list ) {
465             $table->{$name}{$_} and delete $current->{$name}{$_}
466 13   66     94 for @TYPES;
467             };
468              
469             # put it back in place
470 7         21 $self->replace_symbols( \@list, $current );
471             };
472              
473             # This method's signature is a bit counterintuitive:
474             # $self->replace_symbols( \@names_to_erase, \%new_table_entries )
475             # If first argument is omitted, the whole namespace is scanned instead.
476             # Separate erase_symbols and write_symbols turned out to be cumbersome
477             # because of the need to handle granular exclusion list.
478             # This method can fill both roles.
479             # Providing an empty list would make it just write the symbol table,
480             # whereas an empty hash would mean deletion only.
481             sub replace_symbols {
482 27     27   2155 my ($self, $clear_list, $table) = @_;
483              
484 27   100     122 $clear_list ||= [ $self->read_names ];
485 27   100     90 $table ||= {};
486              
487 27         57 my %uniq;
488 27         234 $uniq{$_}++ for keys %$table, @$clear_list;
489              
490             # re-read the symbol table
491 27         164 my $old_table = $self->read_symbols( [ keys %uniq ] );
492              
493             # create a plan for change
494 27         117 my $diff = $self->table_diff( $old_table, $table );
495 27 50       98 return unless keys %$diff;
496              
497 27         104 $self->write_symbols( $diff );
498             };
499              
500             sub filter_functions {
501 14     14   29 my ($self, $table) = @_;
502              
503 14         23 my %new_table;
504              
505 14         65 foreach (keys %$table) {
506             $new_table{$_} = $table->{$_}
507 110 100       271 if defined $table->{$_}{CODE};
508             };
509              
510 14         36 return \%new_table;
511             };
512              
513             # Oddly enough, pure
514             # In: old and new two symbol table hashrefs
515             # Out: part of new table that differs from the old,
516             # with touch_not rules applied
517             sub table_diff {
518 27     27   57 my ($self, $old_table, $new_table) = @_;
519              
520 27         45 my %uniq_name;
521 27         226 $uniq_name{$_}++ for keys %$old_table, keys %$new_table;
522              
523 27         71 my $touch_not = $self->{touch_not};
524              
525 27 100       101 if (my $restrict = $self->{restrict_symbols}) {
526             # If a restriction is in place, invert it and merge into skip
527             # TODO write this better
528             # TODO does it really belong here?
529 1   33     6 $restrict->{$_} or delete $uniq_name{$_} for keys %uniq_name;
530 1         2 my %real_touch_not;
531 1         2 foreach my $name (keys %uniq_name) {
532             # 2 levels of shallow copy is enough
533 2         3 foreach my $type( @TYPES ) {
534             $real_touch_not{$name}{$type}++
535 12 100 66     44 unless $restrict->{$name}{$type} and not $touch_not->{$name}{$type};
536             };
537             };
538 1         3 $touch_not = \%real_touch_not;
539             };
540              
541 27         45 my $diff;
542              
543             # iterate over keys of both, 2 levels deep
544 27         139 foreach my $name (sort keys %uniq_name) {
545 211   50     434 my $old = $old_table->{$name} || {};
546 211   100     444 my $new = $new_table->{$name} || {};
547 211   100     634 my $skip = $touch_not->{$name} || {};
548              
549 211         293 my %uniq_type;
550 211         772 $uniq_type{$_}++ for keys %$old, keys %$new;
551              
552 211         517 foreach my $type (sort keys %uniq_type) {
553 385 100       739 next if $skip->{$type};
554              
555 364 100       778 if (ref $old->{$type} ne ref $new->{$type}) {
556             # As nonrefs are not allowed here,
557             # this also handles undef vs. defined case
558 66         137 $diff->{$name}{$type} = $new->{$type};
559 66         122 next;
560             };
561              
562             # both undef, nothing to see here
563 298 50       521 next unless ref $new->{$type};
564              
565             # pointing to different things
566 298 100       733 if (refaddr $old->{$type} != refaddr $new->{$type}) {
567 4         10 $diff->{$name}{$type} = $new->{$type};
568 4         7 next;
569             };
570             };
571              
572 211 100       518 if ($diff->{$name}) {
573             # if we cannot avoid overwriting,
574             # make sure to copy ALL skipped values we know of
575 49         130 $diff->{$name}{$_} = $old->{$_} for keys %$skip;
576              
577             # removing a scalar copletely didn't work very well on Perl 5.10.1,
578             # causing segfaults in unrelated places.
579 49   100     263 $diff->{$name}{SCALAR} ||= \undef;
580             };
581             };
582              
583 27         134 return $diff;
584             };
585              
586             ### Low-level symbol-table read & write
587             ### no magic should happen above this line
588              
589             # NOTE that even here we are in full strict mode
590             # The pattern for working with raw data is this:
591             # my $value = do { no strict 'refs'; ... }; ## no critic
592              
593             # in: none
594             # out: sorted & filtered list of symbols
595             sub read_names {
596 47     47   81 my $self = shift;
597              
598 47         80 my $package = $self->{target};
599 47         74 my $except = $self->{except_rex};
600 47         72 my $only = $self->{only_rex};
601              
602             my @list = sort grep {
603 1631 100 100     6761 /^\w+$/ and $_ !~ $except and $_ =~ $only
604 47         74 } do {
605 23     23   213 no strict 'refs'; ## no critic
  23         49  
  23         3453  
606 47         63 keys %{ $package."::" };
  47         626  
607             };
608              
609 47         373 return @list;
610             };
611              
612             # In: symbol list arrayref (read_symbols if none)
613             # Out: symbol table hashref
614             sub read_symbols {
615 63     63   137 my ($self, $list) = @_;
616              
617 63         106 my $package = $self->{target};
618 63   100     246 $list ||= [ $self->read_names ];
619 4         10 $list = [ grep { $self->{restrict_symbols}{$_} } @$list ]
620 63 100       166 if $self->{restrict_symbols};
621              
622 63         98 my %content;
623 63         119 foreach my $name ( @$list ) {
624 416         569 foreach my $type (@TYPES) {
625 2496         3081 my $value = do {
626 23     23   170 no strict 'refs'; ## no critic
  23         56  
  23         5132  
627 2496         2917 *{$package."::".$name}{$type};
  2496         4820  
628             };
629 2496 100       5210 $content{$name}{$type} = $value if defined $value;
630             };
631             };
632              
633 63         159 return \%content;
634             };
635              
636             # writes raw symbols, ignoring touch_not!
637             # In: symbol table hashref
638             # Out: none
639             sub write_symbols {
640 45     45   92 my ($self, $table) = @_;
641              
642 45         84 my $package = $self->{target};
643              
644 45         84 if (DEBUG) {
645             my $old_table = $self->read_symbols;
646             $self->message( "package $self->{target} to be altered: ".dump_table($table, $old_table) )
647             };
648              
649              
650 45         133 foreach my $name( keys %$table ) {
651 173         258 my $copy = $table->{$name};
652              
653             {
654 23     23   186 no strict 'refs'; ## no critic
  23         51  
  23         1627  
  173         1741  
655 173         237 delete ${ $package."::" }{$name};
  173         554  
656             };
657              
658 173         432 foreach my $type ( keys %$copy ) {
659 329 100       730 ref $copy->{$type} or next;
660             eval {
661             # FIXME on perls 5.014..5.022 this block fails
662             # because @ISA is readonly.
663             # So we wrap it in eval with no catch
664             # until a better solution is done
665 23     23   162 no strict 'refs'; ## no critic
  23         44  
  23         11860  
666 300         400 *{ $package."::".$name } = $copy->{$type};
  298         889  
667 298         902 1;
668 297 50       413 } || do {
669 4         15 carp "namespace::local: failed to write $package :: $name ($type), but trying to continue: $@";
670             };
671             };
672             };
673             };
674              
675             ### Logging
676              
677             sub dump_table {
678 7     3   23 my ($table, $old_table) = @_;
679              
680 3         6 my @out;
681 3         6 foreach my $name( sort keys %$table ) {
682 3         6 my $glob = $table->{$name};
683 3         9 foreach my $type( sort keys %$glob ) {
684             push @out, "*$name\{$type\}=".(
685             $old_table
686             ? _is_and_was( $glob->{$type}, $old_table->{$name}{$type} )
687 6 50       25 : _ref2str( $glob->{$type} )
688             );
689             };
690             };
691              
692 3         28 return join ", ", @out;
693             };
694              
695             sub _is_and_was {
696 6     6   13 my ($new, $old) = @_;
697              
698 6 50 100     50 if ((refaddr $new || 0) != (refaddr $old || 0)) {
      100        
699 6         14 return _ref2str( $new )."[was: "._ref2str( $old )."]";
700             } else {
701 0         0 return _ref2str( $new )."[unchanged]";
702             };
703             };
704              
705             # TODO find existing?
706             sub _ref2str {
707 12     12   20 my $ref = shift;
708              
709 12 50       85 return ref $ref
    100          
710             ? blessed $ref
711             ? sprintf "%s=%s(0x%x)", ref $ref, reftype $ref, refaddr $ref
712             : sprintf "%s(0x%x)", ref $ref, refaddr $ref
713             : 'undef';
714             };
715              
716             sub message {
717 3     3   8 my ($self, $msg) = @_;
718              
719 3         8 $msg =~ s/\n$//s;
720 3         362 carp "$msg via namespace::local from $self->{origin}";
721             };
722              
723             sub _croak {
724 4     4   42 croak ("namespace::local: ".shift);
725             };
726              
727             =head1 BUGS
728              
729             As of 0.0604, C<-around> hides subroutines defined below its scope end
730             from anything above it.
731             No solution exists so far.
732              
733             This is experimental module. There certainly are more bugs.
734              
735             Bug reports, feature requests, suggestions and general feedback welcome at:
736              
737             =over
738              
739             =item * L
740              
741             =item * L
742              
743             =item * C
744              
745             =back
746              
747             =head1 SUPPORT
748              
749             You can find documentation for this module with the C command.
750              
751             perldoc namespace::local
752              
753             You can also look for information at:
754              
755             =over
756              
757             =item * github:
758              
759             L
760              
761             =item * RT: CPAN's request tracker (report bugs here)
762              
763             L
764              
765             =item * AnnoCPAN: Annotated CPAN documentation
766              
767             L
768              
769             =item * CPAN Ratings
770              
771             L
772              
773             =item * Search CPAN
774              
775             L
776              
777             =back
778              
779             =head1 SEE ALSO
780              
781             L gave the inspiration for this module.
782              
783             L, L and probably more also clean
784             caller's namespace, but differently.
785              
786             L is used as a backend.
787              
788             L explains how reading/writing the namespace works.
789              
790             =head1 LICENSE AND COPYRIGHT
791              
792             Copyright 2018 Konstantin S. Uvarin, C<< >>
793              
794             This program is free software; you can redistribute it and/or modify it
795             under the terms of the the Artistic License (2.0). You may obtain a
796             copy of the full license at:
797              
798             L
799              
800             Any use, modification, and distribution of the Standard or Modified
801             Versions is governed by this Artistic License. By using, modifying or
802             distributing the Package, you accept this license. Do not use, modify,
803             or distribute the Package, if you do not accept this license.
804              
805             If your Modified Version has been derived from a Modified Version made
806             by someone other than you, you are nevertheless required to ensure that
807             your Modified Version complies with the requirements of this license.
808              
809             This license does not grant you the right to use any trademark, service
810             mark, tradename, or logo of the Copyright Holder.
811              
812             This license includes the non-exclusive, worldwide, free-of-charge
813             patent license to make, have made, use, offer to sell, sell, import and
814             otherwise transfer the Package with respect to any patent claims
815             licensable by the Copyright Holder that are necessarily infringed by the
816             Package. If you institute patent litigation (including a cross-claim or
817             counterclaim) against any party alleging that the Package constitutes
818             direct or contributory patent infringement, then this Artistic License
819             to you shall terminate on the date that such litigation is filed.
820              
821             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
822             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
823             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
824             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
825             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
826             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
827             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
828             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
829              
830              
831             =cut
832              
833             1; # End of namespace::local
834