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