In The Well Grounded Rubyist (which, along with The Ruby Way, I
love), Dave Black presents a justification for the x++ omission in
Ruby. I thought I’d see whether I could implement just the
incrementing portion of C’s x++ functionality (without the prefix/
postfix issues) in pure Ruby. I wasn’t willing to delve into Matz’
implementation of higher-level Ruby functions or low-level C/C++
code. Below is what I came up with.
Q1. Test 1 failed, I imagine, because the interpret thought “Ah, 7’s
a Fixnum which I ‘ve seen billions of times, so I know what to do with
it.” Thus, it ignored my over-riding definition of Fixnum. So I
call it “compiler error”, to use the vernacular, by reporting that x
had no method “pp”. Am I all wet?
Test 2 passed, but it with a couple of anomalies:
Q2. x.to_s yielded x’s class and address, suggesting x had become a
“semi-Fixed Num”, i.e, x now stored a REFERENCE to the to x’s data,
rather than the immediate storage of the data, as interpreter is wont
to do with Fixnum’s. Am I all wet?
Q3. y.inspect yielded only it’s value (8) and nothing else,
suggesting the x.pp yielded a full-fledged Fixnum. Am I all wet?
Dave Black argues that since Fixnum values use immediate storage
rather than referenced storage, x=1;x++ would be akin to changing 1
into 2. This example somewhat supports that view, but the
interpreter sidestepped the matter by creating a reference for x’s
value and an immediate value for y (=x.pp).
def initialize (fixnum)
puts “Initializing object %d” % fixnum
raise “Initializer not a Fixnum” if
fixnum.class != Fixnum
puts “\nInitializing Fixnum to %d” % fixnum
@val = fixnum
Test 1 (Failure)
x = 7; y = x.pp; z =x.class # undefined method `pp’ for 7:Fixnum
Test 2 (Success)
x = FixNum.new(7); y = x.pp; z =x.class
puts [x.to_s, y.inspect, z.to_s].join("; ") # => FixNum:0x2b62694;