From: Michael Neumann Date: 2004-08-27T05:23:18+09:00 Subject: Re: python generators to ruby closures, help zuzu wrote: > can anyone help me decode the following python example using > generators into The Ruby Way using closures? Okay, here is it ;-) One problem is, that we can't detect the usage of "break" inside the proc, as we're using proc's and not blocks. My workaround is, that a return value of nil of a proc.call breaks the generator at this position (so make sure to use false and not nil, e.g. "val.nil?" instead just "val"!). Regards, Michael ####### require 'generator' require 'find' alias filter lambda class Generator def |(filter) self.class.new do |g| self.each { |elem| val = filter.call(elem) break if val.nil? g.yield(elem) if val } end end def inspect to_a.inspect end end class Proc def |(otherProc) proc {|*a| x, y = self.call(*a), otherProc.call(*a) break nil if x.nil? or y.nil? x & y } end end def count(n) filter {|i| break if n == 0 n -= 1 i } end def quit(&block) filter {|*a| break if block.call(*a) true } end def gen(&block) Generator.new(&block) end def ints gen {|g| n = 0 loop do g.yield n n += 1 end } end ##### Test odd = filter {|x| x % 2 == 1} notDivBy3 = filter {|x| x % 3 != 0} oddNotDivBy3 = odd|notDivBy3 firstTen = count(10) result = ints | firstTen | oddNotDivBy3 p result oddLowerThanTen = odd | quit {|y| y >= 10} p3 = ints | oddLowerThanTen | notDivBy3 p p3 isRubyFile = filter {|file| File.extname(file).downcase == '.rb'} files = gen {|g| Find.find('.') {|file| g.yield file} } tenRubyFiles = files | isRubyFile | count(10) p tenRubyFiles