Dave Cross: Still Munging Data With Perl: Online event - Mar 17 Learn more

use strict;
no warnings 'redefine';
sub generate_OVERLOAD :Sub(Private)
{
my ($GBL) = @_;
# Overload specifiers
my %TYPE = (
'STRINGIFY' => q/""/,
'NUMERIFY' => q/0+/,
'BOOLIFY' => q/bool/,
'ARRAYIFY' => q/@{}/,
'HASHIFY' => q/%{}/,
'GLOBIFY' => q/*{}/,
'CODIFY' => q/&{}/,
);
my (%code, $code, %meta);
# Generate overload strings
while (my $info = shift(@{$$GBL{'sub'}{'ol'}})) {
$$info{'name'} ||= sub_name($$info{'code'}, ":$$info{'ify'}", $$info{'loc'});
my $pkg = $$info{'pkg'};
my $name = $$info{'name'};
push(@{$code{$pkg}}, "\tq/$TYPE{$$info{'ify'}}/ => sub { \$_[0]->$name() },");
$meta{$pkg}{$name}{'kind'} = 'overload';
}
delete($$GBL{'sub'}{'ol'});
# Generate entire code string
foreach my $pkg (keys(%code)) {
$code .= "package $pkg;\nuse overload (\n" .
join("\n", @{$code{$pkg}}) .
"\n\t'fallback' => 1);\n";
}
# Eval the code string
my @errs;
local $SIG{'__WARN__'} = sub { push(@errs, @_); };
eval $code;
if ($@ || @errs) {
my ($err) = split(/ at /, $@ || join(" | ", @errs));
OIO::Internal->die(
'message' => "Failure creating overloads",
'Error' => $err,
'Code' => $code,
'self' => 1);
}
# Add accumulated metadata
add_meta(\%meta);
no strict 'refs';
foreach my $pkg (keys(%{$$GBL{'tree'}{'td'}})) {
# Bless an object into every class
# This works around an obscure 'overload' bug reported against
bless(\do{ my $scalar; }, $pkg);
# Verify that scalar dereferencing is not overloaded in any class
if (exists(${$pkg.'::'}{'(${}'})) {
(my $file = $pkg . '.pm') =~ s/::/\//g;
OIO::Code->die(
'location' => [ $pkg, $INC{$file} || '', '' ],
'message' => q/Overloading scalar dereferencing '${}' is not allowed/,
'Info' => q/The scalar of an object is its object ID, and can't be redefined/);
}
}
}
} # End of package's lexical scope
# Ensure correct versioning
my $VERSION = 3.09;
($Object::InsideOut::VERSION == 3.09) or die("Version mismatch\n");