[#47955] るびま記事募集:FiberとかSinatra/PadrinoとかBundlerとか — Makoto Kuwata <kwa@...>

桑田といいます。るびま編集部に入りました。

17 messages 2011/04/11

[#48016] 文字列を正規表現にマッチする部分と他の部分に分割 — "5.5" <5.5@...>

5.5 です。

12 messages 2011/04/28

[ruby-list:47977] Re: Fiber#resumeの引数について

From: "5.5" <5.5@...>
Date: 2011-04-15 12:54:43 UTC
List: ruby-list #47977
5.5 です。

(11/04/15 17:55), Satoshi GUNJI wrote:
> 郡司と申します。
> 
> [ruby-list:47973]を見ていてちょっと気になったので、
> Fiberの挙動を確かめるために下記のサンプルコードを実行してみました。
> 
> --------
> f = Fiber.new do
>    Fiber.yield 1
>    Fiber.yield 2
>    Fiber.yield 3
> end
> 
> puts f.resume
> puts f.resume
> puts f.resume
> puts f.resume(8)
> --------
> 
> すると、次のような実行結果となりました。
> 
> --------
> 1
> 2
> 3
> 8
> --------

とくにおかしくはないと思います。
話を簡単にするために規模を縮小します。行番号も付け,
説明の都合上,やりとりする値をシンボルにします。

 1: f = Fiber.new do
 2:   Fiber.yield(:foo)
 3: end
 4:
 5: puts f.resume
 6: puts f.resume(:bar)

5 を評価するとき,まず,f.resume を評価します。すると
f のブロックの中を評価しようとします。
最初に Fiber.yield(:foo) があるので,これを評価しよう
とします。

すると,親ファイバーに戻ってきますが,そのときに :foo
が渡されます。
5 は結局,puts :foo を評価することになります。
ところで,この時点では 2 の評価は終わっていません。

次に 6 を評価しようとします。
まず,f.resume(:bar) を評価しようとします。

すると,また子ファイバーのほうに行きますが,このとき
:bar が子ファイバーのほうへ渡されます。

そして,ようやく 2 の評価が終わります。
Fiber.yield の返り値は,親ファイバーから渡された :bar
です。
※このことはリファレンスマニュアルの Fiber.yield のと
ころに書いてあります。

そして,ブロックの評価は完了しました。
ブロックの評価値は,2 の評価値である :bar です。
ブロックの評価が終わったので,また親ファイバーに戻って
きますが,そのときにブロックの評価値が渡されて,それが
6 の f.resume(:bar) の値となります。
したがって,:bar がプリントされます。

なお,2 を
puts Fiber.yield(:foo)
と書き換えればより理解しやすいと思います。

先に書きましたが,Fiber.yield や Fiber#resume の値を捨
てるようなサンプルスクリプトを使うと理解しづらいです。
私はそれでだいぶ悩みました。

-- 
5.5@moji.gr.jp

In This Thread