Walter, One error is mine, two are yours. > c=cartpord(a.slice(0..-1)) > ... > cartprod.rb:45: undefined method `cartpord' for main:Object > (NoMethodError) You've got a typo here (or -> ro). Also, cartprod is defined as a method of Arrays, so you can't use it as a function like that. > b.each{|be| c=c.cartprod(be) } > ... > cartprod.rb:24:in `cartprod': undefined local variable or method `c' for > [1, 2, 3]:Array (NameError) > from cartprod.rb:49 > from cartprod.rb:49:in `each' > from C:/Documents and Settings/walter/My Documents/cartprod.rb:49 This is a bug in my untested code. It occurs because c is not defined outside the inner block. This version will actually work (I've renamed c to prod): class Array def cartprod(b) prod = ([] unless block_given?) each do |ae| b.each do |be| if block_given? yield ae, be else prod << [ae, be] end end end prod end end > c=cartprod(a) > ... > cartprod.rb:45: undefined method `cartprod' for main:Object > (NoMethodError) Again, cartprod has to be used on an array, like this: a=[[1,2,3],[4,5,6],[7,8,9]] b=a.shift a.each do |ae| b = b.cartprod(ae) # the following line is so you don't get [[[1,4],7], [[1,4],8] ... b.map! {|be| be.flatten } if b[0][0].is_a? Array end b #=> [[1, 4, 7], [1, 4, 8] ... [3, 6, 9]] #(27 elements) But if you want to cartesianly-multiply multiple arrays, maybe you want something more like this: class Array def cartprod return if any? {|a| a.size == 0 } index = [0] * size begin yield *zip(index).map {|a| a[0][a[1]] } (index.size - 1).downto(0) do |i| if index[i] < self[i].size - 1 index[i] += 1 break else index[i] = 0 end end end while index != [0] * size end end This will return nil, but pass the values you want into a given block: a=[[1,2,3],[4,5,6],[7,8,9]] a.cartprod do |a0e, a1e, a2e| # ... end You should easily be able to change it to return an array if you need to. Cheers, Dave