With great power comes great responsibility!
It also might be the case in some future implementations that such a
patch might be ineffective, or intermittently effective.
For example, some Smalltalk implementations, would handle a + b under
the covers as an integer add of the two object pointers and a little
adjustment, followed by a quick check to see if the result were a
fixnum, and only send the :+ message if it wasn't. This check can be
done relatively inexpensively due to the way in which references to
FixNums (or SmallIntegers as Smalltalk called them) are encoded.
If a number x is in FixNum range then it's encoded as a 'pointer' with
the binary value x*2+1 This means that, if the low-order bit set it's
a Fixnum otherwise it isn't. So if we have two object pointers xp and
yp, referring to the objects x and y respectively we can implement x +
y as something like:
result = xp + yp - 1;
if (arithmetic overflow || !(result && 1) ) {
result = send(xp,:+,yp)
}
Note that, if xp and yp refer to Fixnums:
xp + yp - 1
= (x*2+1)+(y*2+1) - 1
= x*2 + y*2 + 1
= (x+y)*2 + 1
which is the correct representation for the FixNum x+y
I don't know whether YARV already does this or might in the future.
This is one of the things which VM implementers tend to look for, they
'cheat' and try not to get caught in the interest of performance.
Now Matz and his team might reject some of these tricks since the
dynamic nature of ruby might make it harder not to be caught, but in
some of these edge cases, I think that case can be made that it's
probably OK since it's unlikely that anyone will actually redefine
basic arithmetic operations on core classes such as FixNum and live to
tell about it without blowing up irb or worse.
···
On 3/14/07, Giles Bowkett <gilesb@gmail.com> wrote:
I just tried something:
Fixnum.class_eval do
def +(number)
self - number
end
end
It blew up my irb.
--
Rick DeNatale
My blog on Ruby
http://talklikeaduck.denhaven2.com/