computer science, math, programming and other stuff
a blog by Christopher Swenson

More Ruby Woes

I have been giving Ruby the old college try. I was running into some strange difficulties with a minimax function in Ruby that at first I thought were more scoping oddities.

It turns out that the clone and dup operators on Arrays in Ruby only perform shallow copying, which will pretty much not work on multidimensional arrays. Oh well, I guess I would have to write my own, or copy someone else's, right? Maybe something like:

def deepcopy(x)
  if x.kind_of? Array
    copy = []
    x.each { |y|  copy += [deepcopy(y)] }
    return copy
  else
    return x.dup
  end
end

Wrong. Ruby's almost-but-not-quite pure-OO nature actually makes it nearly impossible to create a generic deep copy function. The problem is that integers, floats, and so forth are not the complete objects we thought they were, because you can't dup them:

>> x = 1.dup
TypeError: can't dup Fixnum
    from (irb):1:in `dup'
    from (irb):1

So much for pure OO.

The best solution I could come up with for a two-deep copy is (knowing ahead of time that it is a matrix):

def copy2(b)
    newb = []
    b.each { |r|  newb += [r.dup] }
    return newb
end

This, along with the odd scoping rules and counter-intuitive syntax are making me seriously consider ending my Ruby experiment. And I so wanted to love Ruby.