是否可以在Perl中动态指定一个类并访问该类中的静态方法?这不起作用,但说明了我想做的事情:
use Test::Class1;
my $class = 'Test::Class1';
$class::static_method();
Run Code Online (Sandbox Code Playgroud)
我知道我可以这样做:
$class->static_method();
Run Code Online (Sandbox Code Playgroud)
并忽略传递给static_method的类名,但我想知道是否有更好的方法.
Rob*_*t P 10
对!使用限制的方法是使用can.
package Foo::Bar;
use strict;
use warnings;
sub baz
{
return "Passed in '@_' and ran baz!";
}
package main;
use strict;
use warnings;
my $class = 'Foo::Bar';
if (my $method = $class->can('baz'))
{
print "yup it can, and it ";
print $method->();
}
else
{
print "No it can't!";
}
Run Code Online (Sandbox Code Playgroud)
can返回对方法的引用,undef/false.然后,您只需使用dereferene语法调用该方法.
它给:
> perl foobar.pl
yup it can, and it Passed in '' and ran baz!
与Perl一样,有不止一种方法可以做到这一点.
use strict;
use warnings;
{
package Test::Class;
sub static_method{ print join(' ', @_), "\n" }
}
Run Code Online (Sandbox Code Playgroud)
您可以使用特殊%::变量来访问符号表.
my $class = 'Test::Class';
my @depth = split '::', $class;
my $ref = \%::;
$ref = $glob->{$_.'::'} for @depth; # $::{'Test::'}{'Class::'}
$code = $glob->{'static_method'};
$code->('Hello','World');
Run Code Online (Sandbox Code Playgroud)你可以简单地使用一个符号引用 ;
no strict 'refs';
my $code = &{"${class}::static_method"};
# or
my $code = *{"${class}::static_method"}{CODE};
$code->('Hello','World');
Run Code Online (Sandbox Code Playgroud)你也可以使用一个字符串eval.
eval "${class}::static_method('Hello','World')";
Run Code Online (Sandbox Code Playgroud)在这种情况下最简单的就是使用UNIVERSAL::can.
$code = $class->can('static_method');
$code->('Hello','World');
Run Code Online (Sandbox Code Playgroud)我不知道有什么特别好的方法可以做到这一点,但是还有一些不太好的方法,例如这个程序:
#!/usr/bin/perl -w
use strict;
package Test::Class1;
sub static_method {
print join(", ", @_) . "\n";
}
package main;
my $class = "Test::Class1";
{
no strict "refs";
&{${class}. "::static_method"}(1, 2, 3);
}
Run Code Online (Sandbox Code Playgroud)
我已经包含了一个$class变量,因为这就是您提出问题的方式,它说明了如何在运行时选择类名,但是如果您事先知道该类,您可以轻松地调用&{"Test::Class1::static_method"}(1, 2, 3);
strict "refs"请注意,如果您打开了它,则必须将其关闭。