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