2011-09-11 2 views
13

私はPerlクラスのimportメソッドを実装して、Dataオブジェクトをインスタンス化しようとしています。これは本質的にhashrefの適切な配列。ここでくそ、私のオブジェクトを祝福することはできません

は、私はそれを使用する予定の方法の例です:

# 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で何が起こっているかに多くの明快さを追加しませんでした:

Can't bless non-reference value

(F) Only hard references may be blessed. This is how Perl "enforces" encapsulation of objects. See perlobj .


私も、オブジェクトを初期化し、2つの段階に分けてデータを追加してみました:

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. 誰かこのコンパイル時エラーの説明をperldiagで明示してください。
+0

Hindsight:警告/エラーメッセージを理解するために 'perldiag'より優れたリファレンスはありますか? – Zaid

+2

一般に、前提条件のプリントを挿入することで、このようなエラーを攻撃することができます。この場合、あなたのサブルーチンへの引数。 ( 'print" import got:@_ \ n ";')それはあなたが配列であると思ったものが実際にはなかったことをあなたに知らせてくれました。次に、 'ref $ data eq 'ARRAY'のようなガードを追加するか、配列ではないことを告白します: '$ data'";そして、違反の呼び出しがどこから来ているかを知るでしょう。 ( '告白は' Carp 'を告白してから ''告白し、完全なバックトレースを提供する) ''詐欺'に変わって、おそらく将来的に他のエラーを直ちに捕まえるのを助けるかもしれないので、 –

+0

@ Lance Roberts:元のタイトルは、['Acme :: Damn'](http://search.cpan.org/perldoc?Acme::Damn)モジュール(これは、 'bless') – Zaid

答えて

21

import()は、メソッドを与えるために危険な名前ですが、Perlは時には 'import'というメソッドを呼び出します。実際には、声明:

use Data; 

は本当に意味: 'コンパイル' の間に起こる

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

を。

import()メソッドは、クラスローディングメカニズムの一部としてPerlによって呼び出され、使用する機会があります。 import()メソッドの名前を別のもの(たとえばimport_data)に変更する必要があります。

+0

これが事実なら、彼は彼が得ているエラーを得ることはないだろう。 –

+3

はい、そうです。どちらの場合でも、PerlはData-> import()を呼び出すため、$ dataは存在しないため、 'オブジェクトが祝福されない'というエラーが発生し、 '配列を逆参照しない'というエラーが発生します。 – Alex

+0

+1:これは問題で、「読み込み」から「読み込み」に改名されました。私の正気は回復しました。ありがとう! – Zaid

関連する問題