From: shugo@... (MAEDA Shugo) Date: 1998-11-22T00:44:46+09:00 Subject: [ruby-list:11008] Re: スコープの範囲 前田です。 >>>>> In [ruby-list:10996] >>>>> "新井" == Koji Arai wrote: >> 【1】ローカル変数のバインドは静的に行われ、ローカル変数は最初の代 >> 入文で定義される。 >> >> この場合、静的とは、実行前にスクリプトのコード上で、という感じの >> 意味。 >> 新井> 「静的に」という用語が… コンパイル時ということですね。 新井> 「*いかなる場合でも*定義より前の"行"で、ローカル変 新井> 数が有効になることはない」 新井> あってます? だと思います。 >> 【2】イテレータのブロックでは、そこで初めて定義されたローカル変数は >> 局所化される。 >> イテレータではブロック外部のローカル変数(小文字で始まるの変数)にアク >> セス出来る。 新井> 局所化されるかどうかを文法で区別できないのは少し痛 新井> いですね。 新井> イテレータを書くときは、常に局所変数の名前がダブら 新井> ないように気を使わなくてはいけないですから。 変数の宣言がないから仕方がないんですけどね。 いっそのことイテレータブロック(ブロックパラメータでしたっけ?)はスコープ を新たに導入しない方がわかりやすいような気もしますね。 そうすると [0, 1, 2].each {|i|...} p i #=> 2 とできるのがちょっと気になりますが、forはすでにそうなっていることを 考えるとそれほど問題ないとも言えます。 def foo ret = nil iter { ret = ... } return ret end のような場合、最初の宣言のための代入がいらなくなるのは結構うれしいですね。 おまけに、動的ローカル変数の方が速いと思ってたのですが、そうでもない みたいです。 bash-2.01$ time ruby -e '100000.times { i = 0 }' real 0m0.927s user 0m0.880s sys 0m0.050s bash-2.01$ time ruby -e 'i = 0; 100000.times { i = 0 }' real 0m0.768s user 0m0.740s sys 0m0.030s と考えてくると、イテレータブロックが新たにスコープを導入するのは 一体何のためなんでしょう? 名前の衝突を防ぐ効果は新井さんも御指摘の通りないわけですし。 # 何か大事なことを忘れてる気がする(^^; >> 【3】定義は、代入を実行することによってなされるのではなく、実行以前に >> スクリプト中に代入文が現れたときになされる、 >> 新井> そうだったのか〜。「静的」だからかぁ。 だから、 if false foo = "foo" end puts foo もOKというわけです。 -- 前田 修吾 (mailto:shugo@aianet.ne.jp)