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   270 use strict;
  13         15  
  13         328  
4 14     12   1225 use warnings;
  14         978  
  14         344  
5 16     11   1210 no warnings 'redefine';
  15         1132  
  14         4469  
6              
7             sub generate_OVERLOAD :Sub(Private)
8             {
9 13         52 my ($GBL) = @_;
10              
11             # Overload specifiers
12 13         428 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         391 my (%code, $code, %meta);
23              
24             # Generate overload strings
25 13         392 while (my $info = shift(@{$$GBL{'sub'}{'ol'}})) {
  87         179  
26 76 50       478 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     259 $$info{'name'} ||= sub_name($$info{'code'}, ":$$info{'ify'}", $$info{'loc'});
30 75         79 my $pkg = $$info{'pkg'};
31 75         61 my $name = $$info{'name'};
32              
33 75         46 push(@{$code{$pkg}}, "\tq/$TYPE{$$info{'ify'}}/ => sub { \$_[0]->$name() },");
  75         175  
34              
35 75         201 $meta{$pkg}{$name}{'kind'} = 'overload';
36             }
37             }
38 12         24 delete($$GBL{'sub'}{'ol'});
39              
40             # Generate entire code string
41 12         25 foreach my $pkg (keys(%code)) {
42             $code .= "package $pkg;\nuse overload (\n" .
43 14         27 join("\n", @{$code{$pkg}}) .
  14         56  
44             "\n\t'fallback' => 1);\n";
45             }
46              
47             # Eval the code string
48 12         16 my @errs;
49 12         60 local $SIG{'__WARN__'} = sub { push(@errs, @_); };
  0         0  
50 12     11   1667 eval $code;
  11     5   42  
  11         12  
  11         134  
  6         419  
  6         480  
  2         47  
  12         566  
  41         14829  
  1         362  
  1         390  
51 12 50 33     890 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         44 add_meta(\%meta);
62              
63 14     11   1221 no strict 'refs';
  12         240  
  12         1766  
64              
65 12         13 foreach my $pkg (keys(%{$$GBL{'tree'}{'td'}})) {
  12         41  
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         47 bless(\do{ my $scalar; }, $pkg);
  61         74  
70              
71             # Verify that scalar dereferencing is not overloaded in any class
72 61 50       168 if (exists(${$pkg.'::'}{'(${}'})) {
  61         245  
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   59 }
  12         397  
  12         66  
81              
82             } # End of package's lexical scope
83              
84              
85             # Ensure correct versioning
86             ($Object::InsideOut::VERSION eq '4.03')
87             or die("Version mismatch\n");
88              
89             # EOF