该死的,Perl不能祝福我的对象

Zai*_*aid 13 perl bless

除了双关语之外,我正在尝试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
Run Code Online (Sandbox Code Playgroud)

我的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;
Run Code Online (Sandbox Code Playgroud)

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

Can't bless non-reference value at Data.pm line 51.
BEGIN failed--compilation aborted at myScript.pl line 8.
Run Code Online (Sandbox Code Playgroud)

perldiag 并未对发生的事情增加太多清晰度:

不能祝福非参考价值

(F)只有硬参考才能得到祝福.这就是Perl"强制"对象封装的方式.见 perlobj.


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

sub import {                         #< Another constructor >

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

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

    return $obj;
}
Run Code Online (Sandbox Code Playgroud)

这导致以下编译时错误:

Can't use an undefined value as an ARRAY reference...
BEGIN failed--compilation aborted at...
Run Code Online (Sandbox Code Playgroud)

两个问题:

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

Ale*_*lex 21

import()是一个给出方法的危险名称,因为Perl有时会为你调用一个名为'import'的方法.事实上,声明:

use Data;
Run Code Online (Sandbox Code Playgroud)

真正意思:

BEGIN {
    require Data;
    Data->import();
}
Run Code Online (Sandbox Code Playgroud)

这在"编译"期间发生.

因此,在您有机会使用它之前,Perl可能会将您的import()方法作为类加载机制的一部分进行调用.你应该将import()方法重命名为其他东西(例如import_data),你应该没问题.

  • 我一直认为`import`方法应该是'IMPORT`方法,与'DESTROY`和其他语言块如'BEGIN`一起使用.用户/程序员不期望方法的全部小写声明a)具有与任何其他方法不同的含义,并且b)导致此问题. (8认同)
  • 是的,他愿意.在这两种情况下,Perl都会调用Data-> import(),因此$ data永远不存在,导致'no object to bless'错误,以及'no array to dereference'错误. (3认同)