On 4 feb, 19:33, Robert Klemme <shortcut...@googlemail.com> wrote:
> On 04.02.2007 17:13, gga wrote:
>
>
>
> >> I try differently: what kind of class do you want to implement? Why do
> >> you think you need to inherit? What capabilities should instances of
> >> your class have?
>
> > Simple. I want a Fixnum. I don't want to pollute Fixnum's namespace
> > and I don't want a Fixnum to automatically be promoted to my class,
> > while at the same time, my class should be compatible with ALL of
> > fixnum methods (odd? even?, etc).
> > Think of a Year class (yes, I know there's Date and DateTime -- my
> > class is not exactly this but will do as an example). A year is
> > represented by a Fixnum, but it is not a Fixnum.
> > Yet I expect all Fixnum operations to work on it, returning a new Year
> > in case of additions, etc. I also don't want a normal Fixnum to be
> > treated as a year without a conversion function or instantiation thru
> > Year.new(). Also, I want to have a lof of conversion functions within
> > Year that are not applicable to Fixnum ( to_months, to_days, etc ).
>
> Is it a year of the century or years difference? How would you
> implement to_days? I don't think this is worth another class - and btw.
> there are classes for date and time handling in Ruby which support all
> the math you typically need. Plus, you can also define methods in a
> more functional way (i.e. def year_to_months(year) etc.).
Robert, I just made an example for you to understand. I'm not quite
creating a Year class, albeit I am creating something that is somewhat
related ( if you want to know, for video/film work, it is a Frame
class, where a frame represents usually represents 1/24 or 1/30 --or 1/
fps- of a second). As such, I do want to have conversion functions
that will report the length of time the frames represent but in
seconds, minutes, hours, etc. I don't want a Fixnum to be treated as
a Frame, as, for example, in the context I'll be using it, negative
"frames" make no sense.
>
> > Right now, to do that, I have to actually recreate all of the methods
> > in Fixnum/Numeric/etc. while if I was inheriting from it, I would only
> > have to recreate half of them or less or rely on method_missing
> > (yuck).
>
> You can still use delegator...
I can (and as I said, I have already), it is just pretty inelegant and
inefficient. Taking care of kind_of? and similar is pretty messy (but
needed as I do want to have Range of frames, for example).
Therefore, I want to know the reason of WHY I am forced to use a
delegator for deriving one of the most basic classes possible. So
far, I don't know why I need to go through such a cumbersome approach.
>
> It's an internal optimization. Fixnums do not have to be created and
> they never have to be GC'ed. This goes a long way to make math faster
> than it would be with ordinary objects (at least for Fixnums).
>
Very well. It still does not explain much. Why can't I take
advantage of this optimization for my own class? As I showed already,
Fixnums are also allowed to contain additional data and new methods
with them... so I know they are somehow GCed (not the number itself,
but any associated data with the Fixnum class). I don't think Ruby is
doing *that* much of an optimization if you ask me (ie. every operator
always pays the cost of method dispatching). There's obviously a
memory optimization of having the Fixnum be represented by VALUE
itself (instead of it being a pointer to something else), but not much
else, as far as I can tell.
Perhaps I should rephrase my question in a simpler manner. Why does
the Ruby source code contain an undef() of "new" for Numeric and
Floats? Once I understand why those lines in the source code are
there, I can then decide whether indeed a delegator is the one and
only solution to whatever problem those lines are trying to address.
So far, I am seeing it as annoying (and unneeded) limitation.
If I remove those lines from the C code, sure enough I can then
instantiate a Numeric or an Integer through inheritance, but still not
pass a default value to the constructor as the initialize in Integer
fails (it seems it defaults to Object's initialize).
It seems like if I create my own initialize function in C that sets
the FIXNUM flag, but not the IMMEDIATE flag, it should be possible to
create an efficient pseudo-int class that you can inherit from
normally. I understand some of the dangers of this, but I think it
can be done safely, by hacking the ruby source code some more.