File Coverage

blib/lib/Gloom.pm
Criterion Covered Total %
statement 83 106 78.3
branch 19 36 52.7
condition 6 12 50.0
subroutine 16 20 80.0
pod 0 11 0.0
total 124 185 67.0


line stmt bran cond sub pod time code
1             ### This module was derived from Gloom - the Great Little OO Module!
2             ### Read `perldoc Gloom` for more information.
3              
4 3     3   56612 use strict; use warnings;
  3     3   8  
  3         131  
  3         16  
  3         6  
  3         186  
5             package Gloom;
6             our $VERSION = '0.25';
7              
8 3     3   38 use constant XXX_skip => 1;
  3         7  
  3         880  
9              
10             sub import {
11 6     6   61 my ($class, $flag) = @_;
12 6         72 my ($package, $module) = caller(0);
13              
14 6         93 strict->import;
15 6         73 warnings->import;
16              
17 6 100 66     106 if ($class->isa(__PACKAGE__) and
      66        
18             defined $flag and
19             $flag eq '-base'
20             ) {
21 4         18 $class->import_base($package, $module);
22             }
23             else {
24 2         11 require Exporter;
25 2         2025 goto &Exporter::import;
26             }
27             }
28              
29             sub import_base {
30 4     4 0 8 my ($class, $package, $module) = @_;
31 3     3   27 no strict 'refs';
  3         5  
  3         750  
32 4         8 push @{$package . '::ISA'}, $class;
  4         75  
33 4         20 $class->import_fake($package, $module);
34 4         17 $class->export_base($package);
35             }
36              
37             sub import_fake {
38 4     4 0 9 my ($class, $package, $module) = @_;
39 4         20 my $inc_module = $package . '.pm';
40 4         18 $inc_module =~ s/::/\//g;
41 4 100       22 return if defined $INC{$inc_module};
42 3         32 $INC{$inc_module} = $module;
43             }
44              
45             sub export_base {
46 4     4 0 8 my ($source, $target) = @_;
47 3     3   20 no strict 'refs';
  3         5  
  3         1868  
48 4 50       15 for my $sub (map {
  20         79  
49             /::/ ? $_ : "${source}::$_"
50             } $source->EXPORT_BASE()) {
51 20         36 my $name = $sub;
52 20         81 $name =~ s/.*:://;
53 20         54 *{$target . "::$name"} = \&$sub;
  20         3545  
54             }
55             }
56              
57             sub new {
58 2     2 0 25 my $class = shift;
59 2         5 my $self = bless {}, $class;
60 2         12 $self->init(@_);
61 2         5 return $self;
62             }
63              
64             sub init {
65 2     2 0 4 my $self = shift;
66 2         9 while (my ($property, $value) = splice(@_, 0, 2)) {
67 3 50       28 unless ($self->can($property)) {
68 0         0 my $class = ref $self;
69 0         0 require Carp;
70 0         0 Carp::confess("Class '$class' has no property '$property'");
71             }
72 3         68 $self->$property($value);
73             }
74             }
75              
76             my %code = (
77             sub_start =>
78             "sub {\n",
79             set_default =>
80             " \$_[0]->{%s} = %s\n unless exists \$_[0]->{%s};\n",
81             class =>
82             " return do { my \$class = \$_[0]; %s } unless ref \$_[0];\n",
83             init =>
84             " return \$_[0]->{%s} = do { my \$self = \$_[0]; %s }\n" .
85             " unless \$#_ > 0 or defined \$_[0]->{%s};\n",
86             return_if_get =>
87             " return \$_[0]->{%s} unless \$#_ > 0;\n",
88             set =>
89             " \$_[0]->{%s} = \$_[1];\n",
90             onset =>
91             " do { local \$_ = \$_[1]; my \$self = \$_[0]; %s };\n",
92             chain =>
93             " return \$_[0];\n}\n",
94             sub_end =>
95             " return \$_[0]->{%s};\n}\n",
96             );
97              
98             my $parse_arguments = sub {
99             my $paired_arguments = shift || [];
100             my ($args, @values) = ({}, ());
101             my %pairs = map { ($_, 1) } @$paired_arguments;
102             while (@_) {
103             my $elem = shift;
104             if (defined $elem and defined $pairs{$elem} and @_) {
105             $args->{$elem} = shift;
106             }
107             elsif ($elem eq '-chain') {
108             $args->{-chain} = 1;
109             }
110             else {
111             push @values, $elem;
112             }
113             }
114             return wantarray ? ($args, @values) : $args;
115             };
116              
117             my $default_as_code = sub {
118 3     3   22 no warnings 'once';
  3         6  
  3         2143  
119             require Data::Dumper;
120             local $Data::Dumper::Sortkeys = 1;
121             my $code = Data::Dumper::Dumper(shift);
122             $code =~ s/^\$VAR1 = //;
123             $code =~ s/;$//;
124             return $code;
125             };
126              
127             sub has {
128 2     2 0 17 my $package = caller;
129 2         11 my ($args, @values) = &$parse_arguments(
130             [ qw(-package -class -init -onset) ],
131             @_,
132             );
133 2         7 my ($has, $default) = @values;
134 2 50       179 $package = $args->{-package} if defined $args->{-package};
135 2 50       4 return if defined &{"${package}::$has"};
  2         21  
136 2 50 33     191 my $default_string =
    50 33        
137             ( ref($default) eq 'ARRAY' and not @$default )
138             ? '[]'
139             : (ref($default) eq 'HASH' and not keys %$default )
140             ? '{}'
141             : &$default_as_code($default);
142              
143 2         182 my $code = $code{sub_start};
144              
145 2 50       12 if ($args->{-class}) {
146 0 0       0 if ($args->{-class} eq '-init') {
147 0         0 $args->{-class} = $args->{-init};
148 0         0 $args->{-class} =~ s/\$self/\$class/g;
149             }
150 0         0 my $fragment = $code{class};
151 0         0 $code .= sprintf
152             $fragment,
153             $args->{-class};
154             }
155              
156 2 50       7 if ($args->{-init}) {
157 0         0 my $fragment = $code{init};
158 0         0 $code .= sprintf
159             $fragment,
160             $has,
161             $args->{-init},
162             ($has) x 4;
163             }
164 2 50       5 $code .= sprintf $code{set_default}, $has, $default_string, $has
165             if defined $default;
166 2         196 $code .= sprintf $code{return_if_get}, $has;
167 2         6 $code .= sprintf $code{set}, $has;
168 2 50       8 $code .= sprintf $code{onset}, $args->{-onset}
169             if defined $args->{-onset};
170 2 50       5 if (defined $args->{-chain}) {
171 0         0 $code .= $code{chain};
172             }
173             else {
174 2         6 $code .= sprintf $code{sub_end}, $has;
175             }
176              
177 2 50   1   950 my $sub = eval $code;
  1 50       4  
  1         3  
  1         9  
  2         8  
  2         14  
  2         11  
178 2 50       6 die "eval('$code') failed: $@" if $@;
179 3     3   45 no strict 'refs';
  3         21  
  3         2102  
180 2         3 *{"${package}::$has"} = $sub;
  2         19  
181 2 50       12 return $code if defined wantarray;
182             }
183              
184             our $DumpModule = 'YAML::XS';
185 0     0 0 0 sub WWW { require XXX; local $XXX::DumpModule = $DumpModule; XXX::WWW(@_) }
  0         0  
  0         0  
186 0     0 0 0 sub XXX { require XXX; local $XXX::DumpModule = $DumpModule; XXX::XXX(@_) }
  0         0  
  0         0  
187 0     0 0 0 sub YYY { require XXX; local $XXX::DumpModule = $DumpModule; XXX::YYY(@_) }
  0         0  
  0         0  
188 0     0 0 0 sub ZZZ { require XXX; local $XXX::DumpModule = $DumpModule; XXX::ZZZ(@_) }
  0         0  
  0         0  
189              
190             sub EXPORT_BASE {
191 4     4 0 11 return map { __PACKAGE__ . '::' .$_ }
  20         46  
192             qw(has WWW XXX YYY ZZZ);
193             }