Multi-Dispatch
view release on metacpan or search on metacpan
lib/Multi/Dispatch.pm view on Meta::CPAN
prec => q{$params->{precedence}},
sig => $params->{sig},
level => '$params->{level}',
min => $params->{min_args},
max => $params->{max_args},
ID => $multi_ID,
inception => do { no warnings 'once'; ++\$Multi::Dispatch::inception},
code => $declarator $common { no warnings 'redefine'; $code return sub { local *next::variant; *next::variant = pop; local *__ANON__ = q{$name}; <BODY> } },
}, $add_role_variants,
};
}
}
my $implementation = qq{
\@{\$Multi::Dispatch::impl{$name}{$target_package}}
= Multi::Dispatch::_AtoIsort( $existing_variants, $new_variants );
$update_derived_classes
};
my $redispatches = $body =~ /\b next::variant \b/x ? 1 : 0;
my $dispatcher_code = _build_dispatcher_sub( debug => $^H{'Multi::Dispatch debug'},
verbose => $^H{'Multi::Dispatch verbose'},
name => $name,
keyword => $keyword,
as_sub => $redispatches,
invocant => $invocant,
);
# Do we need to clone an existing dispatcher sub that was imported from elsewhere???
my $clone_multi = q{};
if ($keyword eq 'multi' && !$autofrom) {
no strict 'refs';
no warnings 'once';
my $qualified_name = $caller_package.'::'.$name;
if (*{$qualified_name}{CODE}) {
my $info = $Multi::Dispatch::dispatcher_info_for{*{$qualified_name}{CODE}};
if ($info && $info->{package} ne $caller_package) {
$clone_multi = "multi $name :autofrom($info->{package}); BEGIN { no warnings;"
. "\$Multi::Dispatch::closed{'$keyword'}{'$name'}{$target_package}=0;}";
}
}
}
# Some components are unnecessary under :export...
my $BEGIN = q{BEGIN};
my $ISOLATION_TEST = qq{
if (\$Multi::Dispatch::closed{'$keyword'}{'$name'}{$target_package}) {
package Multi::Dispatch::Warning;
warn "Isolated variant of $keyword $name()"
if warnings::enabled('Multi::Dispatch::noncontiguous');
}
else {
\$Multi::Dispatch::closed{'$keyword'}{'$name'}{$target_package} = $noncontiguous;
}
};
if ($export) {
$BEGIN = $ISOLATION_TEST = q{};
}
my $annotator = $^H{'Multi::Dispatch annotate'}
? q{ UNITCHECK { Multi::Dispatch::_annotate(__PACKAGE__, __FILE__) } }
: q{};
my $installer = qq{
$BEGIN {
no strict 'refs';
$ISOLATION_TEST
my \$redefining = $redispatches;
if (*$target_name {CODE}) {
my \$info = \$Multi::Dispatch::dispatcher_info_for{*$target_name {CODE}};
if (!\$info) {
\$redefining = 1;
package Multi::Dispatch::Warning;
warn 'Subroutine $name() redefined as $keyword $name()'
if warnings::enabled('redefine');
}
elsif (\$info->{keyword} ne '$keyword') {
die qq{Can't declare a \$info->{keyword} and a $keyword of the same name ("$name") in a single package};
}
elsif (\$info->{package} ne $target_package ) {
\$redefining = 1;
package Multi::Dispatch::Warning;
warn ucfirst "\$info->{keyword} $name() [imported from \$info->{package}] redefined as $keyword $name()"
if ('$frommodule' ne \$info->{package})
&& warnings::enabled('redefine');
}
}
else {
\$redefining = 1;
}
if (\$redefining) {
no warnings 'redefine';
my \$impl = $declarator $common {
my \@variants = \@{\$Multi::Dispatch::impl{'$name'}{$target_package}//[]};
$dispatcher_code;
};
*$target_name = \$impl;
\$Multi::Dispatch::dispatcher_info_for{\$impl} = {
keyword => '$keyword',
package => $target_package,
};
}
$annotator
$implementation
}
} =~ s/\n//gr
=~ s/<BODY>/_fix_state_vars($body)/egr;
# Install that code (and adjust the line numbering)...
${$src_ref} = $clone_multi . $installer . "\n#line $endline\n" . ${$src_ref};
};
}
# Export the two new keywords...
sub import {
my $package = shift;
if (grep /\A-?debug\Z/, @_) { $^H{'Multi::Dispatch verbose'} = 1;
$^H{'Multi::Dispatch debug'} = 1; }
if (grep /\A-?verbose\Z/, @_) { $^H{'Multi::Dispatch verbose'} = 1; }
if (grep /\A-?annotate\Z/, @_) { $^H{'Multi::Dispatch annotate'} = 1; }
( run in 0.856 second using v1.01-cache-2.11-cpan-39bf76dae61 )