In article <3989168news.pl@insigna.ie.u-ryukyu.ac.jp> kono@ie.u-ryukyu.ac.jp (Shinji KONO) writes:

> In article <3FA32785.3090209@geocities.co.jp>, Masanori HATA <lovewing@geocities.co.jp> writes
> $a,$b は特別扱いされるので使わない方が良いです。どういう
> 意図なのか良くわからないけど、たぶん、eval しないで、sub {}
> と[]とか使った方がいいんじゃないかなぁ。

$a,$bと書いたのは投稿のために簡素化したかったからで、実際にはもっ
と長い変数名を使っています^^;

で、意図についてなんですが、PostgreSQLへの問い合わせ結果を

while (<DB>) {
    my($column1,$column2,$column3) = split /\|/, $_;
    ...処理...
}

というように処理しているのですが、同じコード(各列を変数に代入す
るコード)を含むスクリプトが複数あります。そして、近い将来、列が
追加されることがわかっているので、その時に複数のスクリプトにある

my($column1,$column2,$column3) = split /\|/, $_;

という部分を

my($column1,$column2,$newcolumn,$column3) = split /\|/, $_;

のように書き直すのはメンテナンス制が悪いので、サブルーチンにする
ことを考えました。その時サブルーチンの返す値が配列やハッシュだと、
これまで$column1,$column2,...のようにしていた変数名を全部付け替
えないとなりません。だからと言って、サブルーチンの中で、

($column1,$column2,$column3) = split /\|/, $_;

のようにしてグローバル変数にはしたくない。それで、変数名の付け替
えをせずに、グローバル変数にもせずにサブルーチン化するには、eval
がいいかも知れないと考えたわけです。それで、以下のようなものを書
いてみたら、代入されなかったというわけです:

while (<DB>) {
    $cmd = subroutine();
    eval $cmd;
    ...処理...
}

sub subroutine { #別のファイルに作りrequireする
    my $cmd = 'my($column1,$column2,$column3) = split(/\|/,$_);';
    return = $cmd;
}

畑さんのフォロー<3FA32785.3090209@geocities.co.jp>にあるように、
evalの前にmyすると、列が追加されるたびに、複数のスクリプトを書き
換えることになり、もとの木阿弥です^^;

やはり手抜きをせずに、変数名を付け替えるしかなさそうですX-<

--
    石川 淳            国立感染症研究所
    (Jun Ishikawa)      生物活性物質部第四室
    jun@nih.go.jp       (旧遺伝生化学室)
    Tel. 03-5285-1111   Fax 03-5285-1272
    http://nocardia.nih.go.jp/
    I hate damn sequences!