我可以在Perl中动态指定的类中访问静态方法吗?

chu*_*uck 10 oop perl

是否可以在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!

  • 可能值得一提的是,如果您要查找的静态函数不在用于调用`can()`的包中,那么这种方法将遵循任何`@ISA`定义来尝试在其他基础中找到静态函数从中派生出来的包.这可能是也可能不是你追求的行为. (3认同)
  • @Robert P:在具有父级的模块中,绝对可以很好地使用静态类函数.例如,我今天为一系列缓存处理程序编写了一个缓存处理程序,其中子代中的静态函数包含一些配置信息,这些信息需要在父代中增加某些行为. (2认同)

Bra*_*ert 5

与Perl一样,有不止一种方法可以做到这一点.

use strict;
use warnings;
{
  package Test::Class;
  sub static_method{ print join(' ', @_), "\n" }
}
Run Code Online (Sandbox Code Playgroud)


Tim*_*Tim 4

我不知道有什么特别好的方法可以做到这一点,但是还有一些不太好的方法,例如这个程序:

#!/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"请注意,如果您打开了它,则必须将其关闭。