Черт возьми, Perl не может благословить мой объект - PullRequest
13 голосов
/ 11 сентября 2011

В стороне, я пытаюсь реализовать метод 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 сообщает об ошибке при compile -time (обратите внимание на блок 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 объяснение этой ошибки во время компиляции?

1 Ответ

21 голосов
/ 11 сентября 2011

import () - опасное имя для метода, поскольку Perl иногда вызывает для вас метод с именем import.На самом деле утверждение:

use Data;

действительно означает:

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

, что происходит во время «компиляции».

Так что, вероятно, ваш метод import ()вызывается Perl как часть механизма загрузки классов, прежде чем вы получите возможность его использовать.Вам следует переименовать ваш метод import () во что-то другое (например, import_data), и все будет в порядке.

...