まつもと ゆきひろです
In message "[ruby-list:3032] Re: thread and fork"
on 97/05/29, Jun Kuroda <jkuro / dwe.co.jp> writes:
|黒田です。
| >ですね.ここで「うっかり」イテレータブロックの外側でlogって
| >名前の変数を使っちゃうと痛い目に遭いますが.
|
|外側というのは
|- --
|def session(log)
| log.set構造体
| ...
|end
|
|thread.start{
| log = Log.new
| session(log)
|}
|- --
|
|こういうのもだめなんでしょうか。
いいえ,これはOKです.外側っていうのはスコープのネストの外側
という意味です.ちょっとややこしいので,説明しておきます.
rubyのスコープは基本的には外側がみえません.たとえばdefの内
側から外のローカル変数はみえません.
しかし,例外があります.それはイテレータブロックです.
イテレータブロックは新しいスコープを導入しますが,外側のロー
カル変数もみえるんです.
aaa = 25 # 外側のスコープ(aaaがみえる)
thread.start { # ネストしたスコープ
log = Log.new # aaa,logがみえる
session(log)
} # ネストしたスコープの終り
# logはみえなくなる
これによってthread毎に固有の値を持つローカル変数を使うことが
出来ます.ところが間違ってlogをイテレータブロックの外側で初
期化しちゃうと
log = 25 # logを初期化しちゃった
...
thread.start { # ネストしたスコープ
log = Log.new # 変数logは共有される
session(log) # 外側でlogを変えると痛い目に
}
...
となってしまいます.この辺がちょっとややこしいですね.
まつもと ゆきひろ /:|)