From: matz@... (Yukihiro Matsumoto) Date: 1997-05-29T12:20:08+09:00 Subject: [ruby-list:3033] Re: thread and fork まつもと ゆきひろです In message "[ruby-list:3032] Re: thread and fork" on 97/05/29, Jun Kuroda 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を変えると痛い目に } ... となってしまいます.この辺がちょっとややこしいですね. まつもと ゆきひろ /:|)