So I understand you aren't supposed to to directly subclass Fixnum, Float or Integer, as they don't have a #new method. Using DelegateClass seems to work though, but is it the best way? Anyone know what the reason behind these classes not having #new is?
I need a class which behaves like a Fixnum, but has some extra methods, and I'd like to be able to refer to its value through self
from within the class, for example:
class Foo < Fixnum
def initialize value
super value
end
def increment
self + 1
end
end
Foo.new(5).increment + 4 # => 10
You can pretty easily set up a quick forwarding implementation yourself:
class MyNum
def initialize(number)
@number = number
end
def method_missing(name, *args, &blk)
ret = @number.send(name, *args, &blk)
ret.is_a?(Numeric) ? MyNum.new(ret) : ret
end
end
Then you can add whatever methods you want on MyNum, but you'll need to operate on @number in those methods, rather than being able to call super directly.
IIRC, the main implementation of Ruby stores Fixnums as immediate values, using some of the low bits of the word to tag it as a Fixnum instead of a pointer to an object on the heap. That's why, on a 32-bit machine, Fixnums are only 29-bits (or whatever it is) instead of a full word.
So because of that, you can't add methods to a single "instance" of Fixnum, and you can't subclass it.
If you're dead-set on having a "Fixnum-like" class, you'll probably have to make a class that has a Fixnum instance variable, and forward method calls appropriately.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With