The Perl method call is just regular routines that get invocant as their first value.
use strict;
use warnings;
use 5.10.1;
{
package MyPackage;
sub new{ bless {}, shift }
sub echo{ say @_ }
}
my $package_name = 'MyPackage';
$package_name->echo;
my $object = $package_name->new();
$object->echo;
MyPackage
MyPackage=HASH(0x1e2a070)
If you want to call a routine without invocant, you will need to call it differently.
{
no strict 'refs';
${$package_name.'::'}{echo}->('Hello World');
&{$package_name.'::echo'}('Hello World');
}
$::{$package_name.'::'}{echo}->('Hello World');
$package_name->can('echo')->('Hello World');
can , , invocant. coderef .
my $code_ref = $package_name->can('echo');
$code_ref->('Hello World');
can:
, .
.
{
no strict 'refs';
&{ $package_name.'::echo' }('Hello World');
}
. , , . use strict 'refs';.
, , .
, Stash.
$MyPackage::{echo}->('Hello World');
$::{'MyPackage::'}{echo}->('Hello World');
$main::{'MyPackage::'}{echo}->('Hello World');
$main::{'main::'}{'MyPackage::'}{echo}->('Hello World');
$main::{'main::'}{'main::'}{'main::'}{'MyPackage::'}{echo}->('Hello World');
, $package_name ::
*Some::Long::Package::Name::echo = \&MyPackage::echo;
$::{'Some::'}{'Long::'}{'Package::'}{'Name::'}{echo}('Hello World');
sub get_package_stash{
my $package = shift.'::';
my @package = split /(?<=::)/, $package;
my $stash = \%:: ;
$stash = $stash->{$_} for @package;
return $stash;
}
get_package_stash('Some::Long::Package::Name')->{echo}('Hello World');
. CPAN Package:: Stash.
use Package::Stash;
my $stash = Package::Stash->new($package_name);
my $coderef = $stash->get_symbol('&echo');
$coderef->('Hello World');
( Pure Perl :: Stash , Stash)
/, , Exporter:
*echo = \&{$package_name.'::echo'};
echo('Hello World');
:
{
local *echo = \&{$package_name.'::echo'};
echo('Hello World');
}
, strict 'refs'.