Perl调用从基类导入

时间:2013-01-26 22:14:45

标签: perl oop import base

我有一个名为A的基类:

package A;
use strict;
use warnings;
use v5.12;

sub import {
    my $caller = caller;
say 'import called from ' . $caller;
    if (not $caller->can('has')) {
        no strict 'refs';
say "--> import has to $caller";
        *{"${caller}::has"} = sub { _attr($caller, @_) };
    }
}

sub _attr {
    my ($class, $name, $default) = @_;
    no strict 'refs';
    *{"${class}::$name"} = sub {
        my ($self, $value) = @_;
        $self->{$name} = $value if $value;
        return $self->{$name} // $default;
    };
}

1;

并有一个儿童班B

package B;
use strict;
use warnings;
use lib './';
use base 'A';
use v5.12;

#use C;
A->import();

has 'ans' => 42;
say ans();

1;

如果我正在尝试运行此代码,则会出现语法错误 但如果我将这些更改has 'ans' => 42'改为has('ans' => 42);,那么一切都很有效。

或者,如果我创建了课程C

package C;
use strict;
use warnings;
use lib '.';
use base 'A';

1;

然后我不需要将此代码has 'ans'...修改为has(...,因为一切正常。

所以,我无法理解为什么会这样。 如何在子模块中导入子例程has

1 个答案:

答案 0 :(得分:1)

要将hasA导入任何其他模块,您只需将use A放入该模块即可。

替换此行:

A->import();

使用:

use A;

它会做你想要的。

手动调用->import无法执行您想要的操作,因为它在运行时发生,导入需要在编译时进行,以便perl知道has是在解析使用它的行之前的子例程名称。 use是一个编译时命令,因此在解析has行之前有效。