Write and Run

it's a simple way, but the only way.

Stream2のモヤモヤ

とりあえず、分かったことだけ。

正しいことを書いてるとは限らないよ!! むしろ昨日はじめて stream2 に触ったからツッコミ待ちだよ!! ドキュメントもサンプルコードも少なくて困ってるよ!! 助けて!!

3つのモード

readable stream には stringMode と objectMode、それと名前はついてないけどいわゆる bufferMode がある。で、stringMode と bufferMode はほぼ同一なのでいいとして、問題は objectMode。

ReadableStream#read([size])の挙動

read() は引数 size が省略された場合、キューの全てを返すことが期待される*1

しかし、objectMode の場合、キューの中から1つだけ返されるだけである。引数なしの read() を一度呼べば全てのデータが吸い出せるという前提でコードを書くとこの仕様にぶち殺される気がする。返り値が null になるまで読めという指摘もあるかもしれないが、キューに null を突っ込むこともできる。あちゃー。

個人的には、read(2) とかで [{obj: 1}, {obj: 2}] みたいになってほしい。つまり、キューから size ぶんだけ配列で返してほしい。そうすれば read() のときにも [{obj: 1}, {obj: 2}, {obj: 3}] になるし、中身に null が入っていても [null, {obj: 1}] となるから区別できる。

この意見の妥当性をもう一度自分で確かめられたら本家にアイデア投げてみようかなーと思う。

追記1

ReadableStream のことしか考えてなかった。pipe するときに WritableStream#write に配列が投げられたらアレゲだった。でも、結合不可なデータをストリームに流すのってどうかと思うから、オブジェクトを write するときは write([obj]) にしろ、っていうのも悪くないんじゃないかと思った。そうすれば複数チャンクを一度に書き込めるし。

まだまだ考えてみようと思う。

追記2

Twitter 上で id:Jxck さんにいろいろ指摘をいただきました。現状の Stream2 に対する理解が深まりました。ありがとうございます!

ログをだらだら貼り付けておくので、まとめだけ読みたい人は下へどうぞ。











以下、自分の勝手な解釈。必然的に間違いを含むはず。(てか正解があるなら今すぐ欲しい感)

「書き込む」というとややこしいので、ReadableStream のキューにデータを追加することを「キューに吸い込む」と呼ぶことにする(便宜上)。

まず、ReadableStream には大きく2つのモードがある。それが、objectMode と非 objectMode。キューにデータを吸い込む際、そのデータが string, buffer, null, undefined のいずれでもない場合、自動的に objectMode になる。一度 objectMode になると二度と非 objectMode にはならない。ストリームは object に「汚染」される。

……と、ここまで書きかけて、chunk と呼んでいたものは buffer で、chunk と buffer には区別があるらしいことがわかってしまったので、もう一度まとめ直したい。

あと、コミットログ追っかけてわかったこともあるので、全部まとめ直します、はい……

追記3

リンク張ってなかったけど、続き書きました→ 続: Stream2のモヤモヤ - Write and Run

*1:参照: http://nodejs.org/docs/v0.9.9/api/stream.html#stream_readable_read_size