【问题标题】:Perl - How create method alias in child class?Perl - 如何在子类中创建方法别名?
【发布时间】:2013-04-17 20:03:19
【问题描述】:

我正在尝试为子类中的超类泛型方法创建别名,但它似乎不起作用。同一个类中的这个技巧有效,但它似乎不适用于超级/子转换。这是一个真实的基本示例。前两个电话有效。第三次调用产生关于未定义子程序的错误。我也尝试过使用 SUPER::cat,但这也没有用。

package foo;

sub cat{
  print("inside foo\n");
}

*bird = \&cat;

package bar;

use base 'foo';

*dog = \&cat;

package main;

foo::cat();
foo::bird();
bar::dog();

【问题讨论】:

    标签: perl class


    【解决方案1】:

    您对面向对象的继承和简单的符号导入感到困惑。

    正如你所说,use base 'foo' 声明了一个超类。这意味着将检查foo 是否有任何对未出现在bar 中的方法的调用。

    但是*dog = \&cat 不是一个方法调用:它只是一个全局赋值,所以搜索不会超出&bar::cat

    如果您正在编写真正面向对象的代码,那么像这样分配给*bar::dog 会破坏继承机制的意义。

    要观察 Perl 的面向对象功能,请将 glob 赋值移动到 foo(它只是为方法设置别名)并使用方法调用语法进行调用。

    在此代码中,bar 没有自己的方法,并从foo 继承所有内容,但代码按预期工作。

    package foo;
    
    sub cat {
      print("inside foo\n");
    }
    
    *bird = \&cat;
    *dog = \&cat;
    
    
    package bar;
    
    use base 'foo';
    
    
    
    package main;
    
    bar->cat();
    bar->bird();
    bar->dog();
    

    输出

    inside foo
    inside foo
    inside foo
    

    【讨论】:

    【解决方案2】:

    这个:

    *dog = \&cat;
    

    应该是:

    *dog = \&foo::cat;
    

    【讨论】:

    • 确实有效。我只是不清楚为什么我需要它。 “使用基础”不应该将所有父方法导入我的子类吗?
    • "use base" 与基类建立ISA关系
    【解决方案3】:

    你应该写

    sub dog { shift->cat(@_) }
    

    (基本上 eta 转换 cat 方法)而不是使用 glob 赋值,以便 bar 的子类可以覆盖或扩展 cat 而不会破坏 barcat 和 @987654327 的约定@ 做同样的事情。

    【讨论】:

      【解决方案4】:

      将 Borodin 提出的想法更进一步,假设您正在执行正确的 OO,但确实想要父类提供的方法的别名,并且仅在此子类中(以及更深层次)。在这种情况下,您可能想要这样:

      #!/usr/bin/env perl
      
      package foo;
      
      sub new { return bless {}, shift }
      
      sub cat{
        print("inside foo\n");
      }
      
      *bird = \&cat;
      
      package bar;
      
      use base 'foo';
      
      sub dog { $_[0]->can('cat')->(@_) }
      
      package main;
      
      my $bar = bar->new;
      $bar->cat();
      $bar->bird();
      $bar->dog();
      

      此机制在堆栈跟踪中保留dog。如果你不想这样做,你可以使用goto &sub 表单,但既然你应该知道原因才应该这样做,我不打算在这里举个例子。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多