File Coverage

blib/lib/Object/InsideOut/Overload.pm
Criterion Covered Total %
statement 52 59 88.1
branch 3 6 50.0
condition 3 11 27.2
subroutine 7 7 100.0
pod n/a
total 65 83 78.3


line stmt bran cond sub pod time code
1             package Object::InsideOut; {
2              
3 13     13   275 use strict;
  13         14  
  13         329  
4 14     12   1226 use warnings;
  14         897  
  14         342  
5 16     11   1179 no warnings 'redefine';
  15         1255  
  14         4421  
6              
7             sub generate_OVERLOAD :Sub(Private)
8             {
9 13         61 my ($GBL) = @_;
10              
11             # Overload specifiers
12 13         426 my %TYPE = (
13             'STRINGIFY' => q/""/,
14             'NUMERIFY' => q/0+/,
15             'BOOLIFY' => q/bool/,
16             'ARRAYIFY' => q/@{}/,
17             'HASHIFY' => q/%{}/,
18             'GLOBIFY' => q/*{}/,
19             'CODIFY' => q/&{}/,
20             );
21              
22 13         371 my (%code, $code, %meta);
23              
24             # Generate overload strings
25 13         426 while (my $info = shift(@{$$GBL{'sub'}{'ol'}})) {
  87         193  
26 76 50       487 if ($$info{'ify'} eq 'EQUATE') {
27 0         0 push(@{$code{$$info{'pkg'}}}, "\tq/==/ => sub { (ref(\$_[0]) eq ref(\$_[1])) && (\${\$_[0]} == \${\$_[1]}) },");
  0         0  
28             } else {
29 75   66     257 $$info{'name'} ||= sub_name($$info{'code'}, ":$$info{'ify'}", $$info{'loc'});
30 75         82 my $pkg = $$info{'pkg'};
31 75         51 my $name = $$info{'name'};
32              
33 75         75 push(@{$code{$pkg}}, "\tq/$TYPE{$$info{'ify'}}/ => sub { \$_[0]->$name() },");
  75         170  
34              
35 75         197 $meta{$pkg}{$name}{'kind'} = 'overload';
36             }
37             }
38 12         21 delete($$GBL{'sub'}{'ol'});
39              
40             # Generate entire code string
41 12         29 foreach my $pkg (keys(%code)) {
42             $code .= "package $pkg;\nuse overload (\n" .
43 14         25 join("\n", @{$code{$pkg}}) .
  14         58  
44             "\n\t'fallback' => 1);\n";
45             }
46              
47             # Eval the code string
48 12         14 my @errs;
49 12         60 local $SIG{'__WARN__'} = sub { push(@errs, @_); };
  0         0  
50 12     11   1704 eval $code;
  11     46   43  
  11         16  
  11         133  
  6         429  
  6         491  
  2         64  
  12         545  
  41         10859  
  1         356  
  1         406  
51 12 50 33     875 if ($@ || @errs) {
52 0   0     0 my ($err) = split(/ at /, $@ || join(" | ", @errs));
53 0         0 OIO::Internal->die(
54             'message' => "Failure creating overloads",
55             'Error' => $err,
56             'Code' => $code,
57             'self' => 1);
58             }
59              
60             # Add accumulated metadata
61 12         42 add_meta(\%meta);
62              
63 14     11   1192 no strict 'refs';
  12         302  
  12         1656  
64              
65 12         13 foreach my $pkg (keys(%{$$GBL{'tree'}{'td'}})) {
  12         38  
66             # Bless an object into every class
67             # This works around an obscure 'overload' bug reported against
68             # Class::Std (http://rt.cpan.org/Public/Bug/Display.html?id=14048)
69 61         46 bless(\do{ my $scalar; }, $pkg);
  61         72  
70              
71             # Verify that scalar dereferencing is not overloaded in any class
72 61 50       159 if (exists(${$pkg.'::'}{'(${}'})) {
  61         302  
73 0         0 (my $file = $pkg . '.pm') =~ s/::/\//g;
74             OIO::Code->die(
75 0   0     0 'location' => [ $pkg, $INC{$file} || '', '' ],
76             'message' => q/Overloading scalar dereferencing '${}' is not allowed/,
77             'Info' => q/The scalar of an object is its object ID, and can't be redefined/);
78             }
79             }
80 12     11   58 }
  12         402  
  12         60  
81              
82             } # End of package's lexical scope
83              
84              
85             # Ensure correct versioning
86             ($Object::InsideOut::VERSION eq '4.04')
87             or die("Version mismatch\n");
88              
89             # EOF