Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

my in eval

8 views
Skip to first unread message

j...@nih.go.jp

unread,
Oct 31, 2003, 5:02:18 AM10/31/03
to
以下のコードを実行すると、$a,$b,$cに何も代入されないのですが、
myを削除するとうまくいきます。どうしてなのでしょうか?


$data = "1 2 3";
$cmd = 'my($a,$b,$c)=split(/\s/,$data);';
eval $cmd;
print "$a $b $c\n";

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

Masanori HATA

unread,
Oct 31, 2003, 10:06:11 AM10/31/03
to
j...@nih.go.jp wrote in message news:<JUN.03Oc...@watson.nih.go.jp>...
> 以王踉擦離魁・・ドを・・孫圓垢襪函・・・$a,$b,$cに何も代入されないのですが・髟阡・・w)・・?・:ぢを削除するとう瘢雹まくいきます。どう瘢雹してなのでしょう瘢雹か?

>
> $data = "1 2 3";
> $cmd = 'my($a,$b,$c)=split(/\s/,$data);';
> eval $cmd;
> print "$a $b $c\n";

これは・髟阡・・w)w)纐瘡??・Gめ・も・ゃ・・齔跚龠・・?・・応皆・・w)頏蜴龠め・も・ゃ・・・・樌・・・・u丘凾タをやっているのと同じになると思います。
myは変数の値をスコ・踉札廖蕗・???で囲われたブロックの)内に特・・豌修靴等・w)め・も・ゃ?凾タをレキシカル変数にする宣言ですから・髟阡・・頏蜴齷ぢ文に登・・譴垢・・w)グロ・踉札丱詈竸齷・?「甃?「皙?「・とは別物という瘢雹ことになり・髟阡・・頏蜴齷ぢ文の
$a, $b, $cは未定義値として扱われます。

my($a, $b, $c);
eval { ($a, $b, $c) = split / /, '1 2 3'; };
print $a, $b, $c, "\n";

とすれば・髟阡・・纐瘡ブロックの内側瘢雹の $a, $b, $cと外側瘢雹でmy宣言した
$a, $b, $cは同じものとして使う瘢雹ことになると思います。

--
Masanori HATA

Masanori HATA

unread,
Oct 31, 2003, 10:24:53 PM10/31/03
to
畑です。

# googleからだと文字化けしてうまく投稿出来ませんでした。:(

j...@nih.go.jp wrote:
> 以下のコードを実行すると、$a,$b,$cに何も代入されないのですが、
> myを削除するとうまくいきます。どうしてなのでしょうか?
>
>
> $data = "1 2 3";
> $cmd = 'my($a,$b,$c)=split(/\s/,$data);';
> eval $cmd;
> print "$a $b $c\n";

このコードはもう少し整理して書くと

eval { my($a, $b, $c) = split / /, '1 2 3'; };


print $a, $b, $c, "¥n";

と等価だと思います。

myは変数をそのスコープ( {} で囲まれたブロック)の内側に
特殊化する(レキシカル変数にする)宣言ですから、このeval
ブロックの内側と外側の $a, $b, $c はそれぞれ別個の変数と
して扱われることになります。
つまり、print文の結果は、未定義の $a, $b, $c に対してな
されることになります。

$a, $b, $c のmy宣言と、evalブロックでの代入を両方やりたい
場合は、

my($a, $b, $c);
eval { ($a, $b, $c) = split / /, '1 2 3'; };
print $a, $b, $c, "¥n";

とするのがいいと思います。

--
Masanori HATA

Shinji KONO

unread,
Nov 1, 2003, 9:57:43 AM11/1/03
to
河野真治 @ 琉球大学情報工学です。

In article <3FA32785...@geocities.co.jp>, Masanori HATA <love...@geocities.co.jp> writes


> my($a, $b, $c);
> eval { ($a, $b, $c) = split / /, '1 2 3'; };
> print $a, $b, $c, "\n";
> とするのがいいと思います。

$a,$b は特別扱いされるので使わない方が良いです。どういう
意図なのか良くわからないけど、たぶん、eval しないで、sub {}
と[]とか使った方がいいんじゃないかなぁ。


---
Shinji KONO @ Information Engineering, University of the Ryukyus,
河野真治 @ 琉球大学工学部情報工学科,

Yasushi Shinjo

unread,
Nov 1, 2003, 10:05:55 AM11/1/03
to
新城@筑波大学情報です。こんにちは。

In article <JUN.03Oc...@watson.nih.go.jp>
j...@nih.go.jp writes:
> 以下のコードを実行すると、$a,$b,$cに何も代入されないのですが、
> myを削除するとうまくいきます。どうしてなのでしょうか?

「うまくいく」ということは、元々代入したいわけですね。

どうしてかと問われると、答えとしては、代入したい時と
代入したくない時があって、それを区別するために、my を
付けたり付けなかったりすることで区別するようにした、
という答えも可能なんだろうけれど、

> $data = "1 2 3";
> $cmd = 'my($a,$b,$c)=split(/\s/,$data);';
> eval $cmd;
> print "$a $b $c\n";

インタプリタ作ったら、たまたまそうなったという話もありそうな
気もするし。

sh だとこうなりました。sh に my はないか。
------------------------------------------------------------


$ data="1 2 3"

$ cmd='set $data'
$ eval $cmd
$ echo $1 $2 $3
1 2 3
$
------------------------------------------------------------

\\ 新城 靖 (しんじょう やすし) \\
\\ 筑波大学 電子・情報       \\

j...@nih.go.jp

unread,
Nov 3, 2003, 10:45:10 PM11/3/03
to

> In article <3FA32785...@geocities.co.jp>, Masanori HATA <love...@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...@geocities.co.jp>にあるように、
evalの前にmyすると、列が追加されるたびに、複数のスクリプトを書き
換えることになり、もとの木阿弥です^^;

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

0 new messages