13

除了双关语之外,我试图import在我的 Perl 类中实现一个方法来实例化一个Data对象,该对象本质上是一个美化的 hashrefs 数组,来自适当的 hashrefs 数组。

这是我计划如何使用它的示例:

# Pull in the data
my $data = Data->import(
                         [
                           { a => 1, b => 7, c => 3},
                           { a => 7, b => 9, c => 2},
                         ]
                       );

$data->manipulate;  # Use package methods

我的import实现如下:

package Data;

sub initialize {
    my $class = shift;
    my $data = [];
    bless $data, $class;
    return $data;
}

sub import {

    my ( $class, $data ) = @_;

    bless $data, $class;
    return $data;
}

1;

令人惊讶的是 Perl编译时报告错误(注意BEGIN块):

Can't bless non-reference value at Data.pm line 51.
BEGIN failed--compilation aborted at myScript.pl line 8.

perldiag并没有使正在发生的事情变得更加清晰:

不能保佑非参考价值

(F)只有硬引用可能会受到祝福。这就是 Perl 如何“强制”封装对象。见 perlobj


我什至尝试在两个单独的步骤中初始化对象并添加数据:

sub import {                         #< Another constructor >

    my ( $class, $data ) = @_;

    my $obj = $class->initialize;
    push @$obj, @$data;

    return $obj;
}

这导致了以下编译时错误:

Can't use an undefined value as an ARRAY reference...
BEGIN failed--compilation aborted at...

两个问题:

  1. 我所做的有什么问题?
  2. 有人可以澄清perldiag这个编译时错误的解释吗?
4

1 回答 1

21

import() 是一个危险的命名方法,因为 Perl 有时会为您调用一个名为“import”的方法。事实上,声明:

use Data;

真正意思:

BEGIN {
    require Data;
    Data->import();
}

这发生在“编译”期间。

因此,您的 import() 方法很可能在您有机会使用它之前被 Perl 作为类加载机制的一部分调用。您应该将您的 import() 方法重命名为其他名称(例如 import_data),这样就可以了。

于 2011-09-11T10:04:42.363 回答