From: EGUCHI Osamu Date: 2000-01-05T02:23:42+09:00 Subject: [ruby-dev:8822] Re: BEGIN as stmt. ? えぐち@エスアンドイー です。 >>> In message [ruby-dev:8821] Re: BEGIN as stmt. ? On Tue, 4 Jan 2000 22:45:15 +0900, matz@netlab.co.jp (Yukihiro Matsumoto) said: matz> まつもと ゆきひろです matz> matz> In message "[ruby-dev:8820] BEGIN as stmt. ?" matz> on 00/01/04, EGUCHI Osamu writes: matz> | % ruby -e 'BEGIN {} while true' matz> | -e:1: [BUG] Segmentation fault matz> | Abort (core dumped) matz> | matz> |となってしまいます。 matz> matz> こりはバグです。BEGINでなくても matz> matz> () while true matz> matz> でも発生しますね。要するに修飾型whileのbody部のチェックを怠っ matz> ていたわけです。修正します。末尾にパッチを添付します。 なるほど BEGIN ではなく、 while(と until)側の問題でしたか、 #そういえば、else のない if の else 側のノードは NULL ですものね。 そういう目で観ると、-@ と +@ にも同じバグがありますね、パッチつけます。 # () の値って nil 、ですよね、、、、他の言語みたいですけど(笑) matz> |なんとなく気持は判るのですが、BEGIN (と END)が独自のスコープを持たずに matz> |トップレベルで評価された方が、「なるべくグローバル変数は使いたくない」 matz> |という気持を満足できると思うのですが、如何でしょうか? matz> matz> ENDは独自のスコープを持ちません。BEGINだけです。なぜなら matz> BEGINはプログラム全体が実行される前に実行されるので、その時 matz> 点では(トップレベルスコープも含めて)他のスコープはまだ存在し matz> ませんが、ENDの場合には利用できる周囲にスコープが存在するか matz> らです。 なるほど、END がスコープを独自に持たない理由は判りました。 matz> BEGINが外側のスコープを利用するのだとすると、それはどのスコー matz> プであるべきなのでしょうか? いまだ存在しない周囲のスコープ matz> を利用すると言うのもつらい話ですし、どこにあってもトップレベ matz> ルスコープと言うのも(厳密な意味でのトップレベルスコープが存 matz> 在しないことを考えると)どこまで意味があるか疑問です。 BEGIN はてっきり、トップレベルで評価されるとばかり思っていました。 ruby -nle 'BEGIN {n = 0}; n += 1; END {print n}' /etc/passwd こんな感じの、コードが通る事を期待していた訳です。 #実際は、n=0 の n は BEGIN ブロックの終了で消失するので # n+=1 で、nの 未設定で undefined method `+' for nil (NameError) 周囲のスコープを利用すると言うのは、構文的にネストした場合だと思いますが、 いまのところ BEGIN はトップレベル以外には置けないので、 トップレベルスコープを仮定しても、問題はないと思います。 が、なんとなくネストしていても、動いてしまっているような気もする... そもそも、スコープ以前にネストした BEGIN がどういう意味を持つべきか? は微妙に思えます。(エラーでいいんだろうか?) matz> 厳密な意味でのトップレベルスコープが存在しないというのは、た matz> とえば、loadしたライブラリの評価時のスコープはトップレベルス matz> コープのコピーだということです。ライブラリ実行中に BEGIN が matz> 評価されたら、そのスコープはどのスコープであるべき? たしかに load されたライブラリの中の BEGIN ブロックは悩ましいですね。 ところで、トップレベルのスコープの複製を作るのは何ででしたっけ? #load されたライブラリはトップレベルではなさそなので BEGIN は #使えないものだとばかり思ってました。 ^^;; えぐち Wed Jan 5 02:14:46 2000 EGUCHI Osamu * parse.y: Fix SEGV on empty parens with UMINUS or UPLUS. Index: parse.y =================================================================== RCS file: /usr/home/eguchi/cvs.netlab.co.jp/ruby/parse.y,v retrieving revision 1.11 diff -d -u -r1.11 parse.y --- parse.y 1999/12/14 06:49:47 1.11 +++ parse.y 2000/01/04 17:10:47 @@ -713,7 +713,7 @@ } | tUPLUS arg { - if (nd_type($2) == NODE_LIT) { + if ($2 && nd_type($2) == NODE_LIT) { $$ = $2; } else { @@ -722,7 +722,7 @@ } | tUMINUS arg { - if (nd_type($2) == NODE_LIT && FIXNUM_P($2->nd_lit)) { + if ($2 && nd_type($2) == NODE_LIT && FIXNUM_P($2->nd_lit)) { long i = FIX2LONG($2->nd_lit); $2->nd_lit = INT2FIX(-i);