In article <3BE44A80.21C4DC65 / path.berkeley.edu>, Joel VanderWerf <vjoel / PATH.Berkeley.EDU> wrote: >mrcode / mediaone.net wrote: > >> >> But overall I think Joel VanderWerf's Enumerable tools are probably better >> thought out and implemented than my version. I'll probably be adding that >> to my list of useful libraries. > >There's something a little different about the product operator I >defined. It returns a new "proxy" enumerable which delegates to the >given ones (the factors of the product). So, in the current version >(**), you can't just pass a block to it, you have to call each on the >return value of product: > > require 'enum/op' > include EnumerableOperator > > a = [(0..20), (43..150), ['z','yz','xyz','xz','zz']] > product(*a).each do |width, length, hight| > puts "width is: #{width}, length is: #{length}, hight is: #{hight}" > end > >However, this allows use of 'for', which is very readable: > > for width, length, hight in product(*a) > puts "width is: #{width}, length is: #{length}, hight is: #{hight}" > end > >Also, you can chain with other iterations without generating the >intermediate collection, which may be large: > > product(*a).select { |w, l, h| w > 18 && l < 45 && h == 'zz' } > >---- >(**) With a small change, you can pass a block and have product behave >like cascade. Just define product as follows: > > def product(*factors, &block) > if block > Product.new(*factors).each &block > else > Product.new(*factors) > end > end > >Now you can leave out the ".each": > > product(*a) do |width, length, hight| > puts "width is: #{width}, length is: #{length}, hight is: #{hight}" > end > This is all very useful and cool.... any possiblity that it will end up in Ruby's built-in library? Phil