【问题标题】:How to get reference to parent class subroutine perl如何获取对父类子例程perl的引用
【发布时间】:2015-03-29 22:51:12
【问题描述】:

我有一种情况,在子类中,我需要对父类中定义的子例程的引用,我需要将其传递给将执行它们的其他类。 所以我写了下面的示例模块来测试它。

Parent1.pm

package Parent1;

sub new {
    my ($class, $arg_hash) = @_;

    my $self = bless $arg_hash, $class; 

    return $self;
}

sub printHello{

    print "Hello\n";
}

sub printNasty{
    print "Nasty\n";
}
1;            

Child1.pm

package Child1; 

use base Parent1;

sub new {
    my ($class, $arg_hash) = @_;

    my $self = bless $arg_hash, $class; 

    return $self;
}

sub testFunctionReferences{

    my ($self) = @_;

    # Case 1: Below 2 lines of code doesn't work and produces error message "Not a CODE reference at Child1.pm line 18."
    #my $parent_hello_reference = \&$self->SUPER::printHello;
    #&$parent_hello_reference();

    # Case 2: Out of below 2 lines of code, 1st line executes the function and produces output of "Hello\n" but 2nd line doesn't work and produces error message "Not a CODE reference at Child1.pm line 23."
    #my $parent_hello_reference2 = \$self->SUPER::printHello;
    #&$parent_hello_reference2();

    # Case 3: does not work either. Says "Undefined subroutine &Child1::printNasty called at Child1.pm line 27"
    #my $parent_nasty_reference = \&printNasty;
    #&$parent_nasty_reference();

    # Case 4: works. prints "World\n" as expected  
    #my $my_own_function_reference = \&printWorld;
    #&$my_own_function_reference();

    # Case 5: works. prints "Hello\n" and  "Nasty\n" as expected
    #$self->printHello();
    #$self->SUPER::printNasty();

    # Case 6: does not work produces error "Undefined subroutine &Child1::printHello called at Child1.pm line 38" 
    #printHello();
    return;
}

sub printWorld{
    print "World\n";
}   

test.pl

#!/usr/bin/perl

use Child1;

my $child = Child1->new({});

$child->testFunctionReferences();

所以我的问题是:

  1. 与案例 1 一样,获取对父子例程的引用的正确语法是什么?

  2. 当我使用继承时,如何像案例6一样直接调用父函数?在perl中甚至可能吗?

  3. 如果案例 5 有效,那么为什么不案例 6?

感谢任何见解。谢谢

【问题讨论】:

    标签: perl oop inheritance reference


    【解决方案1】:

    如果printHello是一个子程序,使用

    my $sub = \&Parent::printHello;
    

    如果printHello是一个方法,使用

    # This line must appear inside of the Child package.
    my $sub = sub { $self->SUPER::method(@_) };
    

    如果你想要一个代码引用,你需要一个子例程来引用,这会创建一个。


    在这两种情况下,您都可以使用调用 sub

    &$sub();
    

    $sub->();
    

    (我发现后者更干净,但它们在其他方面是等效的。)

    【讨论】:

    • 谢谢。第一个案例有效,我也理解了。但是您能否解释一下在方法的情况下正在做什么以及如何解释该代码?我们也可以避免传递@_ 吗?
    • 这是一个由方法调用组成的匿名子。这是一个捕获 $self闭包,因此即使您返回它并且$self 不再在范围内,它也可以工作
    【解决方案2】:

    我想出了另一种方法,使用“UNIVERSAL”模块“can”方法获取对父类子例程的引用。

    #Parent.pm
    
            package Parent;
    
            sub new {
                my ($class, $arg_hash) = @_;
                my $self = bless $arg_hash, $class; 
                return $self;
            }
    
            sub printHello{
                print "Parent Hello Called\n";
            }
    
            1;
    
    
    #Child.pm
            package Child;
            use base Parent;
    
            sub new {
                my ($class, $arg_hash) = @_;
                my $self = bless $arg_hash, $class; 
                return $self;
            }
    
            sub getParentSubReference{
                my ($self) = @_;
                return $self->can('printHello');
            }  
    
            1;
    
    
    #test.pl
    
            #!/usr/bin/perl
            use Child;
    
            my $obj = Child->new({});
            my $ref = $obj->getParentSubReference();
            &$ref();
    
    
    #Output
            Parent Hello Called
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-17
      • 2016-05-11
      • 1970-01-01
      • 2013-02-06
      • 1970-01-01
      相关资源
      最近更新 更多