- PR -

Perl ってオブジェクトこうやって書いちゃいけない?

1
投稿者投稿内容
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-07-12 18:37
以下の箇所で実行エラーが生じます。

Can't call method "TitleGet" on an undefined value at ./xxxxxxx.pl line xxx.

もちろん、TitleGet() メソッドは全てのクラスに実装されています。
なので「もしや、こうやって使っちゃいけないのかな?」と不安になっております。

コード:

;#***********************************************************************************************
;# ListProcessDataGet
;#***********************************************************************************************
sub ListProcessDataGet {
my($processIndex) = @_;

local(*x) = ProcessObjectCreate($processIndex);
my($title) = $x->TitleGet(); ←ここで実行エラー!!!!!!!!
my($value) = $x->DataGet();
undef($x);

return($title, $value);
}

;#***********************************************************************************************
;# ProcessObjectCreate
;#***********************************************************************************************
sub ProcessObjectCreate {
my($processIndex) = @_;

local($x);
my($p) = $OrderProcessNames[$processIndex - 1];
{
if ($p eq ProcessNames::Pattern()) { $x = new Pattern(); break; }
if ($p eq ProcessNames::RemakePattern()) { $x = new RemakePattern(); break; }
if ($p eq ProcessNames::CompleteProcess()) { $x = new CompleteProcess(); break; }
if ($p eq ProcessNames::Inspect()) { $x = new Inspect(); break; }
if ($p eq ProcessNames::ExternalInspection()) { $x = new ExternalInspection(); break; }
if ($p eq ProcessNames::FactoryShip()) { $x = new FactoryShipDate(); break; }
if ($p eq ProcessNames::ActualShip()) { $x = new ActualShip(); break; }
}
return(*x);
}


このように、メソッド内でオブジェクトを生成して、これを戻り値にするような書き方はできないものなのでしょうか?


[ メッセージ編集済み 編集者: R・田中一郎 編集日時 2006-07-12 19:20 ]
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-07-12 19:51
すみません。お騒がせしました。

生成する側のメソッドの戻り値ですが、local で指定してたいたため、メソッドから抜けて消滅していたため、ということのようです。

本来なら、以下のように書くのが素直な書き方なのでしょう。
コード:

sub ObjectCreate {
local(*x) =@_;
$x = new Class();
}


でも、できるものなら戻り値は「local(*object) = ObjectCreate();」のように関数の左辺に書きたいのです。

以下のように書けば良いのはわかるのですが、これだと $x のスコープは、このメソッドの名前空間全体になってしまいます。
コード:

sub ObjectCreate {
$x = new Class();
return(*x);
}


そこで引き続きご質問させて下さい。
「local(*object) = ObjectCreate();」
このように書く良い方法はないものでしょうか?

[ メッセージ編集済み 編集者: R・田中一郎 編集日時 2006-07-12 19:53 ]
paniponi-x
常連さん
会議室デビュー日: 2006/01/14
投稿数: 27
投稿日時: 2006-07-18 02:15
なんで ObjectCreate で my を使わないのですか?

ああ、型グロブ使ってるんですね。
ここで型グロブが必要になるわけが今ひとつ飲み込めないのですが。

[ メッセージ編集済み 編集者: paniponi-x 編集日時 2006-07-18 02:18 ]

[ メッセージ編集済み 編集者: paniponi-x 編集日時 2006-07-18 02:21 ]
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-07-18 08:55
引用:

paniponi-xさんの書き込み (2006-07-18 02:15) より:

なんで ObjectCreate で my を使わないのですか?


ん?

コード:
sub ObjectCreate {
    my($x) = new Class();
    return(*x);
}



「何故こう書かないのか?」ってことですか?
型グロブを使わない方法という意味が、よく理解できません。
型グロブを使わないで書くとどのようになるのでしょうか?

#何か、基本的なことを習得し忘れている予感・・・orz
大ベテラン
会議室デビュー日: 2006/06/28
投稿数: 116
投稿日時: 2006-07-19 00:11
ListProcessDataGetでの
コード:
local(*x) = ProcessObjectCreate($processIndex);



コード:
my $x = &ProcessObjectCreate($processIndex);


にして、

ProcessObjectCreateでの
コード:
{

if ($p eq ProcessNames::Pattern()) { $x = new Pattern(); break; }
if ($p eq ProcessNames::RemakePattern()) { $x = new RemakePattern(); break; }



}
return(*x);



コード:
if    ($p eq ProcessNames::Pattern())               { new Pattern();       }

elsif ($p eq ProcessNames::RemakePattern()) { new RemakePattern(); }




とするような方法を試してみたことはあります。
オブジェクト変数をルーチン内で明記できないので、newした後処理できないのが難点です。


[ メッセージ編集済み 編集者: 暁 編集日時 2006-07-19 06:43 ]
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-07-19 15:11
引用:

暁さんの書き込み (2006-07-19 00:11) より:

オブジェクト変数をルーチン内で明記できないので、newした後処理できないのが難点です。


いえいえ、この方法で十分です。

こんな書き方ができたんですね!
おかげですっきり書くことができました。
ありがとうございます。
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-07-19 15:12
引用:

暁さんの書き込み (2006-07-19 00:11) より:

オブジェクト変数をルーチン内で明記できないので、newした後処理できないのが難点です。


いえいえ、この方法で十分です。

こんな書き方ができたんですね!
おかげですっきり書くことができました。
ありがとうございます。

[ メッセージ編集済み 編集者: R・田中一郎 編集日時 2006-07-19 18:47 ]

[ メッセージ編集済み 編集者: R・田中一郎 編集日時 2006-07-19 18:48 ]
1

スキルアップ/キャリアアップ(JOB@IT)