Playing with numbers.

by Gregory Brown

This will not come as a surprise to the experienced Rubyist, but for those in the crowd who are just learning, here is a bit of neat trivia for you to ponder.

Well, we all know that Fixnums (i.e. 1,2,3..) are objects in Ruby, right?
If you didn't, now you do!

So it's easy to do little tricks like

class Fixnum
def +(other)
self - ( -1 * other ) - 2
end
end


which will break your math and let you impress people who are new to open class systems.
(i.e. 4 + 9 == 11 with the above definition)

You could also do functional hacks like

class Fixnum
def squared
self ** 2
end
end


and get yourself 2.squared == 4

But one thing that I didn't think about until Gary Wright mentioned it on RubyTalk is how Fixnums can have instance variables!


class Fixnum
attr_accessor :letter
end

('a'..'z').each_with_index { |letter, index| index.letter = letter }


now 0.letter == 'a', 1.letter == 'b', etc etc

Is this useful? I'm not really sure, to be quite honest. But it sure is neat!
See the discussion in it's original context at: http://www.ruby-forum.com/topic/50170

If you get any killer ideas for how to use such a feature, drop a comment here or there.

2 Comments

Dav
2006-02-13 11:21:09
I'm still pretty new to Ruby and I was working with some STATUS constants one night and had the sudden insight that I could probably add a 'text' instance variable to the Fixnums to hold the human readable textual representation of each particular status. So similar to your :letter instance var I was able to do this


ITEM_STATUS_NEW = 0
ITEM_STATUS_NEW.text = "New Item"


I thought I was pretty clever, until I realized that I couldn't reuse 0 in any other status categories (for instance I had CUSTOMER_STATUS_CLOSED = 0 elsewhere in my code) as all references to 0 were to the same Fixnum object (and you can't clone a Fixnum of course).

gregory brown
2006-02-13 11:46:44
That is pretty clever, but as you mentioned, doesn't work properly.


Probably get the same functionality of Constants of OpenStructs


ITEM_STATUS_NEW = OpenStruct.new(:text => "New Item")


This would let you add more data down the line as well


Maybe a Status singleton would be even better though?