ヽ(´・肉・`)ノログ

How do we fighting without fighting?

ElixirでStreamではないものをStream化するイディオム

ストリームではないものをストリーム化したい場合,一定時間ごとにポーリングして値を取得することになる.

その場合 Stream.interval/1 と,Stream.zip/2Stream.resource/3 を組み合わせるとほとんどの場合にやりたいことに対応できるだろう.

これはフルコースなので,もうちょっと簡単に使いたいときは Stream.resource/3 を Stream.repeatedly/1 に変えたりするとよい.

Stream.resource/3 については

などで実例をみることができる.

「例えば 1 秒毎に 5 回現在時刻を表示する」は以下のように書ける.

Stream.repeatedly(fn -> :erlang.time end)
|> Stream.each(&IO.inspect/1)
|> Stream.zip(Stream.interval(1000))
|> Enum.take(5)
#> {21, 44, 46}
#> {21, 44, 47}
#> {21, 44, 48}
#> {21, 44, 49}
#> {21, 44, 50}

21 時 44 分 46 秒に始まって,21 時 44 分 50 秒に終わっていることがわかるだろう.

この 1 行目を「HTTP 経由で RSS を取得する」や「File の監視」にすると,簡単に一定間隔時間でポーリングした結果を流してくれる Stream になる.

このエントリーをはてなブックマークに追加