From: Tanaka Akira Date: 2009-05-10T15:57:33+09:00 Subject: [ruby-dev:38419] Re: Enumerable#gather_each In article <86ocu132gq.knu@iDaemons.org>, "Akinori MUSHA" writes: > nil の扱いの特殊性(捨てるのでなくそれ単独で、という意味づけ)とか、 なるほど。これについてはいま議論がありますが、いくつかの値に ついては特殊な意味があるということになれば、一般化されてそう いうものだという気になるかもしれません。 > gather という名前のせいかも知れませんが同じ値が再出しても前とは > 関係ないというあたりですかねえ。 これはまつもとさんの印象と同じですね。連続した値しかまとまら ないという気分をかもしだす名前があったら提案していただけると ありがたいです。 >  最初の例というのが >> arg = lambda {|l| /\A\=~ l ? true : nil } > で読めなかったのですが、 l == "\n" でしたか。 あぁ、すいません。そこは /\A\s/ =~ l です。 パラグラフの例は最初のメール [ruby-dev:38392] のもうちょっと 下に出てきます。 > これは > > prev, s.status = s.status, (e == "\n") > b.flush if prev != b.status > b << e > > くらいで悪くはないと思います。b.status != nil のところは、上記の > 「空なら flush しない」で手当てするとして。 それでも gather_each のほうがずっと短いですよね。 >  やりすぎかもしれませんが、 status/status= を提供するのなら、 > prev_status や status_changed? も用意するという手はあります。 私としては、状態変化をユーザが意識する必要はない用途は充分に 多いと考えています。 状態変化をそうやってサポートするのは、状態変化をユーザが意識 する必要がある用途には有用でしょう。しかし、まずそういう用途 が充分に多いのかという点について議論が必要ではないでしょうか。 >  区切るだけなら確かに1行で済みますが、実際にはサンプルコード辺か > どうかを判定したり、前後の空行を除いたりと最終結果までの道のりは > 長いので何とも言えません。要らない部分まで集めて(gather)いますが、 > 本当はもっと複雑な処理が必要なので buffer のようなものがあれば、 > 取捨や加工についても引き受けることができると思いました。 後でやればいいんじゃないでしょうか。gather はまとめるだけで 情報を捨てませんし。 >  上記の通り、実際に考えるべきことが後ろに残ると思うので、 gather > 単体の提供する機能が中途半端に思えたのです。すなわち、インデント > レベル等、分類の基準として計算した値(ブロックの評価値)を捨てて > しまっていますが、この例でも、後段でまた必要になりそうですよね。 インデントの深さは、むしろ後から計算するほうがいいんじゃない でしょうか。インデントされたブロックでは、複数の行のうち、もっ とも浅いインデントが欲しそうですよね。 もし、どうしても分類の値が必要だということであれば、yield す る配列にインスタンス変数としてつけておく (必要ならそれを参照 するアクセサも) のにはやぶさかではありません。 > ということであれば、 buffer を使って gather 等を実装するのは容易 > なので、複数のメソッドを用意するのなら、実装を共有するためにも > buffer のような汎用のものを持つメリットがあるということになるの > ではないでしょうか。 実装してみましたが、そういうものがなくてもそれほど面倒ではあ りませんでした。 汎用のものを用意するのは、汎用のものが必要な例が出てきてから でいいんじゃないでしょうか。 >  buffer は1回のイテレーションで複数の値を push したり複数回 > flush したり(あるいはしなかったり)でき、またイテレータ引数で > なく任意の値を push できるので、 lexer などを実装できます。 > >  というか、 scanf.rb をパースする例を見て、実際の延長上には > lexer のようなものがあるんじゃないかと推測しました。 複雑なことができるからいろんな用途があるに違いない、という話 ではなく、具体的な例はありませんか? -- [田中 哲][たなか あきら][Tanaka Akira]