October 10, 2005
04:33 PM

Digging around a bit more in array.c I uncovered the weirdness described below. In this example Ruby's semantics are either bizzare or just plain broken. It's difficult to understand if and when it's actually possible to override built-in behaviour consistently.

class MyArray < Array
       def to_s
               "my array"
       end
end

class MyHash < Hash
       def to_s
               "my hash"
       end
end

a = MyArray.new
a[0] = 1

b = Array.new
b[0] = 1

c = MyHash.new
c[0] = 1

d = Hash.new
d[0] = 1

puts a.to_s
puts b.to_s
puts c.to_s
puts d.to_s
puts
puts [a, b, c, d].join("\n")

Expected output:

my array
1
my hash
01

my array
1
my hash
01

Actual output:

my array
1
my hash
01

1
1
my hash
01

Why does this happen? Because the implementation of Array.join special cases elements of Array to check for infinite recursion but then statically dispatches to the built-in Array.join implementation.

Again, like the problem in my previous entry this is easy to fix. But is this a bug, or just unusual but planned semantics? Unfortunately answering that question and then finding and fixing issues like this is incrediably difficult in a language where the implementation is the only specification.

© Douglas Stockwell 2007
Creative Commons License Unless otherwise specified all "source code" examples are available for use under the Creative Commons Attribution-Noncommercial 3.0 License. Please contact me if you would like more flexible licensing terms.
Messenger Presence