【问题标题】:Perl - With overriden method avoid super() is calledPerl - 使用覆盖方法避免调用 super()
【发布时间】:2017-08-14 08:43:21
【问题描述】:

我正在尝试使用 Perl 和 Moose 创建抽象方法模式。我不明白的是,如果我重写 AbstractClass 中的方法,它最终还是会被调用。为什么会这样?有没有办法避免调用超类?

主要

package main;
use AbstractSort;
use OrderedSort;

# Sub class test
my $ordered = OrderedSort->new(array => [1, -1, 23, 34123, -24324]);
$ordered->sortData();

抽象类

package AbstractSort;
use namespace::autoclean; # Trims EXPORTER 
use Moose;

has 'array' => (traits  => ['Array'],
            is => 'ro', 
            isa => 'ArrayRef[Int]', 
            default => sub { [] },
            handles => {    
                get_array => 'get',
                count_array  => 'count',
            });

sub sortData{
    my $self = shift;

    print "Sorting data..\n";

    _sortAlgorithm($self->array);

    # ...
}

# Protected method here is the actual algorithm
sub _sortAlgorithm {
    die 'You must override _sortAlgorithm() in a subclass';
    # but Moose will always call the superclass which then makes it die
} 

子类

package OrderedSort;
use namespace::autoclean; # Trims EXPORTER 
use Moose;
extends 'AbstractSort';

# Override and mmpl _sortAlgorithm
override _sortAlgorithm => sub {
   my $self = shift;
   # ....
};

before '_sortAlgorithm' => sub {
    my $self = shift;
    # ...

    return;
};

【问题讨论】:

  • 你确定吗?请出示minimal reproducible example。如果我将包添加到您的代码中,它对我有用。没看到die,先调用before处理程序。
  • 我已经用一个测试示例编辑了帖子

标签: perl perl-module moose


【解决方案1】:

您将 _sortAlgorithm 作为 AbstractSort` 中同一包中的函数调用,而不是作为方法调用。

sub sortData {
    my $self = shift;

    # there is something missing here!
    _sortAlgorithm( $self->array );
}

这样,它总是会在同一个包中被调用,因为它不是 OOP 方法调用。

你需要改为$self->_sortAlgorithm

sub sortData {
    my $self = shift;

    print "Sorting data..\n";

    $self->_sortAlgorithm( $self->array );

    # ...
}

它现在不再是die,因为它在$self 上查找_sortAlgorithm 方法,这是您的子类的一个实例。

事实上,您在被覆盖的方法上有 my $self = shift 可能已经泄露了这一点,因为您也没有将 $self 传递给它。


您也不应该到处乱转$self->array。算法方法也可以访问$self->array,所以如果你想对附加到对象的数据进行排序,直接在里面使用即可。

另请注意,Perl 中的典型命名约定建议使用 snake_case 方法和变量名称,以及 CamelCase 包名称。

【讨论】:

    猜你喜欢
    • 2012-05-01
    • 2023-01-07
    • 1970-01-01
    • 2011-11-13
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    相关资源
    最近更新 更多