Thanks, Robert, for the answer, but it still does not fully explain
why it works like this.
Note that you generally should not use #kind_of? and like methods (->
Duck Typing).
I understand what you want to say but to have a class behave EXACTLY
like a numeric class, it should mimic the behavior of those functions,
too. By using delegation, I'm forced to do two checks for it, which
sucks.
Inheriting from Fixnum is not a a good idea since instances cannot be
constructed as Wolfgang pointed out.
Obviously, I already found about that. But the fact that it works
like that does not explain WHY this is so. There's no reason, afaik.
Even thou in C Fixnums as stored as a single value, you can still do
stuff like:
class Fixnum
attr_accessor :x
end
# create a new fixnum class with some additional x data
a = 10
a.x = 20
a.x
20
# create another one
b = 50
b.x = 100
b.x
100
# copy it
a = b
a.x
100
which means Fixnum has some place where it stores additional methods
and data and its "copy constructor" knows how to properly duplicate
the whole class, without me needing to use dup. Which means to me
Numerics SHOULD be inheritable as is.
The way to go is delegation, as
you did.
I know, but I am trying NOT to. Doing so is a big mess. Plus, I
don't get any additional methods other users may add to Numeric or
Fixnum or have to rely on method_missing which then blocks you from
calling the original's Numeric method_missing (bad idea).
You can however inherit any of the other classes in the
inheritance chain of Fixnum:
irb(main):006:0> 1.class
=> Fixnum
irb(main):007:0> 1.class.ancestors
=> [Fixnum, Integer, Precision, Numeric, Comparable, Object, Kernel]
One of Integer, Precision or Numeric seems most appropriate.
You think I have not tried it? Try any of these:
Fixnum.new(20)
Integer.new(20)
Precision.new(20)
Numeric.new(20)
ALL of them are abstract classes, without a new method. You simply
CANNOT inherit from any numeric class (or, to put it more correctly,
you can, but you cannot instantiate the object afterwards which makes
this kind of useless). Period. It still makes no sense to me why, and
seems more like a big issue to me.
Few hints: there is "delegate" which greatly simplifies this task.
http://ruby-doc.org/stdlib/libdoc/delegate/rdoc/index.html
Delegate is pretty weak. The ancestors method, for example, is not
handled correctly.
Also, if you want to do math you should implement #coerce. Note that
unary operators have an at appended:
Well. That's the kind of stuff I was HOPING to avoid by inheriting
from it. Numeric#coerce as is should work fine for my own class. I
shouldn't have to rewrite it (or several other functions, for that
matter). I should, of course, have to rewrite operators that return
the original base type, but not everything else.
irb(main):016:0> class Foo; def -@; "minus" end end
This tidbit is indeed useful. I didn't know about the unary operator
in ruby.