From: Shin-ichiro HARA Date: 2001-05-17T15:30:47+09:00 Subject: [ruby-dev:13226] Re: [ruby-list:29672] Re: Enumerator 原です。 この問題、このメーリングリストでも長年の懸案なので、今度こそ 決めてもらいたいです。(^^ で、なんでややこしいかというと、色んなパターンがあり得てなか なか仕様を絞れないんですね。でも、なんとか解決しそうなので、 期待しています。 と言いつつ、ちょっと後退させてしまうかもしれないですが、幾つ かコメント。(^^; > a = Enumerator[s, :each_byte].with_index.collect { |b,i| "#{i}: #{b}" } これですが、やっぱり s.Enumerator[:eac_byte].with ... みたいに 繋げて書きたいという欲求がどうしてもあり、何とか出来ないでしょう か。 Enumerator というクラスですが、ほとんどダミーですよね。それをあ えてクラスとして定義する必要はあるのか。例えば、匿名のオブジェク トでも十分では?例えばこんな風に、、、 def Enumerable.[](enumobj, method, *args) e = Object.new.extend self e.instance_eval do @enumobj = enumobj @method = method @args = args end def e.each(&block) @enumobj.send(@method, *@args, &block) end def e.with_index() Enumerable[self, :each_with_index] end e end if __FILE__ == $0 s = 'abcde' a = Enumerable[s, :each_byte].with_index.collect { |b,i| "#{i}: #{b}" } puts a end それから、既に話が出ていますが、これは Enumerable に限ったことではなく、 他のモジュールでも似たことをしたくなるのではないか。それなら最初から汎用 の形を取っていたほうが得策かも。例えば次のような仕様はどうでしょう。 module S def self.[](iter) iter = iter.id2name if iter.is_a? Symbol mod = Module.new mod.module_eval <<-end_ def [](enumobj, method, *args) e = Object.new e.extend self def e.set_instance_var(*a) @mod, @enumobj, @method, *@args = a end e.set_instance_var(self, enumobj, method, *args) def e.#{iter}(&block) @enumobj.send(@method, *@args, &block) end e end end_ mod end end Enumerable.extend S[:each] if __FILE__ == $0 s = 'abcde' a = Enumerable[s, :each_byte].collect { |b| b } puts a end まずはこのぐらいで。