File Coverage

blib/lib/Package/Generator.pm
Criterion Covered Total %
statement 55 55 100.0
branch 18 18 100.0
condition 11 13 84.6
subroutine 11 11 100.0
pod 3 3 100.0
total 98 100 98.0


line stmt bran cond sub pod time code
1 4     4   104741 use strict;
  4         12  
  4         181  
2 4     4   25 use warnings;
  4         11  
  4         281  
3             package Package::Generator;
4             {
5             $Package::Generator::VERSION = '1.106';
6             }
7 4     4   105 use 5.008;
  4         12  
  4         175  
8             # ABSTRACT: generate new packages quickly and easily
9              
10 4     4   31 use Carp ();
  4         9  
  4         93  
11 4     4   29 use Scalar::Util ();
  4         12  
  4         1066  
12              
13              
14             my $i = 0;
15             my $unique_part = sub { $i++ };
16             my $make_unique = sub { sprintf "%s::%u", $_[0], $_[1]->() };
17              
18             sub new_package {
19 22     22 1 46636 my ($self, $arg) = @_;
20 22   100     128 $arg->{base} ||= 'Package::Generator::__GENERATED__';
21 22   66     99 $arg->{unique_part} ||= $unique_part;
22 22   66     96 $arg->{make_unique} ||= $make_unique;
23 22   100     97 $arg->{max_tries} ||= 1;
24              
25 22         26 my $package;
26 22         39 for (my $i = 1; 1; $i++) {
27 26         83 $package = $arg->{make_unique}->($arg->{base}, $arg->{unique_part});
28 26 100       146 last unless $self->package_exists($package);
29 7 100       562 Carp::croak "couldn't generate a pristene package under $arg->{base}"
30             if $i >= $arg->{max_tries};
31             }
32              
33 19 100       70 my @data = $arg->{data} ? @{ $arg->{data} } : ();
  2         8  
34              
35 19 100       76 push @data, (
    100          
    100          
36             ($arg->{isa} ? (ISA => (ref $arg->{isa} ? $arg->{isa} : [ $arg->{isa} ]))
37             : ()),
38             ($arg->{version} ? (VERSION => $arg->{version}) : ()),
39             );
40              
41 19 100       41 if (@data) {
42 5         15 $self->assign_symbols($package, \@data);
43             } else {
44             # This ensures that even without symbols, the package is created so that it
45             # will not be detected as pristene by package_exists. Without this line of
46             # code, non-unique tests will fail. -- rjbs, 2006-04-14
47             {
48             ## no critic (ProhibitNoStrict)
49 4     4   28 no strict qw(refs);
  4         7  
  4         126  
  14         17  
50 4     4   20 no warnings qw(void);
  4         5  
  4         516  
51 14         20 %{$package . '::'};
  14         106  
52             }
53             }
54              
55 18         213 return $package;
56             }
57              
58              
59             sub assign_symbols {
60 5     5 1 8 my ($self, $package, $key_value_pairs) = @_;
61              
62 5 100       187 Carp::croak "list of key/value pairs must be even!" if @$key_value_pairs % 2;
63              
64             ## no critic (ProhibitNoStrict)
65 4     4   21 no strict 'refs';
  4         8  
  4         676  
66 4         18 while (my ($name, $value) = splice @$key_value_pairs, 0, 2) {
67 11         21 my $full_name = "$package\:\:$name";
68              
69 11 100 100     50 if (!ref($value) or Scalar::Util::blessed($value)) {
70 6         7 ${$full_name} = $value;
  6         57  
71             } else {
72 5         6 *{$full_name} = $value;
  5         56  
73             }
74             }
75             }
76              
77              
78             sub package_exists {
79 39     39 1 3271 my ($self, $package) = @_;
80              
81 39         54 return defined *{$package . '::'};
  39         233  
82             }
83              
84             # My first attempt! How silly I felt when I threw in some Data::Dumper and saw
85             # that the above would suffice. -- rjbs, 2006-04-14
86             #
87             # my @parts = split /::/, $package;
88             #
89             # my $current_pkg = 'main';
90             # for (@parts) {
91             # my $current_stash = do { no strict 'refs'; \%{$current_pkg . "::"} };
92             # return unless exists $current_stash->{$_ . "::"};
93             # $current_pkg .= "::$_"
94             # }
95             # return 1;
96              
97             1;
98              
99             __END__