From: GOTOU Yuuzou Date: 2001-05-24T23:23:52+09:00 Subject: [ruby-dev:13325] Re: Enumerator -- Round 2 ごとうゆうぞうです。 In message <86pucz9cu5.wl@archon.local.idaemons.org>, `"Akinori MUSHA" ' wrote: > > files = Find['.'].select { |f| File.file?(f) } > > などということができてとても便利になります。ユーザからは特に > Enumerator という存在は見えませんが、ライブラリ側からすると、 > この陰の存在によって手軽に Enumerable なオブジェクトを生成して > 返すことが可能になっています。 そう思います。似たようなことを考えていました。 > # 実は、 Enumerator の改良案を練っていたのですが、 C API 的に > # あまりうれしさがないことと、使い方の具体例が思い浮かばない > # ことで頓挫してしまいました。現行の提案仕様で十分かも。;) 組み込みが目標なので、もっと進めましょう ^^; self を返しているようなイテレータはブロックをもらわない場合は、 Enumerator を返すようになれば便利だと思います。 module Find alias find0 find def find(*path) if iterator? find0(*path){ |e| yield e } else Enumerator.new(self, :find0, *path) end end module_function :find module_function :find0 end module Enumerable alias each_with_index0 each_with_index def each_with_index if iterator? each_with_index0{ |e,i| yield(e,i) } else Enumerator.new(self, :each_with_index0) end end end すると、次のようにメソッドチェーンが記述できます。 Find::find("/tmp").each_with_index.collect{ |e,i| [i, e] } この調子で拡張して行けば、 1.upto(10).each_slice(2).collect{ |a| a } #=> [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] 等も可能だし、名前もそのままでいいように思います。 # これを each_なんとか という名前のまま使っても違和感がなけれ # ば、というのが前提ですけど。 この仕様だと、全体にばらまかなければ嬉しさが半減するのですが、 さすがに影響が大きすぎるように思います。そこで、ひとまず enumerator.rb で再定義して使ってみるというのはどうでしょうか。 それから、本題と外れますが、alias した関数は module_function し直さないと LocalJumpError になってしまうのは、仕様でしょうか? $ cat f.rb require 'find' module Find alias find0 find end Find::find("/tmp") $ ruby -v f.rb ruby 1.7.0 (2001-05-22) [i386-netbsd1.5U] /usr/local/lib/ruby/1.7/find.rb:15:in `find': yield called out of block (LocalJumpError) from /usr/local/lib/ruby/1.7/find.rb:14:in `catch' from /usr/local/lib/ruby/1.7/find.rb:14:in `find' from f.rb:5 -- ごとうゆうぞう