stream closedと言われた夜
作業してたの昼だけど。
scalaでgzip圧縮されているtsvを読んで、行毎にcase classのインスタンスに変換して、Seqで返すメソッドを書いてたんだけど、当該メソッドの戻り値のSeqにアクセスしたらstream closedって言われてしまった。
こんなコード
scala2.12で呼び出し元でstream closedになるケース
行をよしなにする処理は、メソッドの第二引数procに指定する。
この書き方だと、戻り値のSeqにアクセスしたときにstream closedと言われ、実行時例外が走る。
streamってどっから出てきたん?
って思いました。私はScalaザコ助なので。
ソース確認したらTraversableOnce.scalaに以下のようにある。
def toSeq: Seq[A] = toStream
APIドキュメントには以下のようにあった
Converts this traversable or iterator to a sequence. As with toIterable, it's lazy in this default implementation, as this TraversableOnce may be lazy and unevaluated.
Scala Standard Library 2.12.11 - scala.collection.TraversableOnce
oh.... > its.lazy
よって上記のメソッドの戻り値はStream[A]になってるわけだ。
読み込み元はcloseしてるので、当然Streamにはアクセスできない
finallyでcloseしてますからね。そりゃあ呼び出し元でアクセスしたらstream closedって言われるわけだ。
今回の用途だと、ファイルを全て読み込んでしまって問題なかったので、toSeqじゃなくてtoListを使うことで対応した。
なお、Scala2.13ではtoSeqはListを返すようになっているようだ。