[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

subclassing fundamental classes

jeevan

5/8/2007 7:18:00 AM

Let's say I have a user-defined class as follows:

class C1
#-------------------------
def initialize(i, j)
@iv1 = Array.new(i, j)
end
#-------------------------
def append(i)
@iv1 << i
return(self)
end
#-------------------------
def append2X(i)
@iv1 << 2 * i
return(self)
end
#-------------------------
end

Now I subclass C1 to make C2:

class C2 < C1
#-------------------------
def initialize(inA)
@iv1 = inA
end
#-------------------------
def append(i)
@iv1 << i << i
return(self)
end
#-------------------------
def doubleLast()
@iv1[-1] *= 2
return(self)
end
#-------------------------
end

The internal state of the superclass (C1) is visible to methods in the subclass
(C2) and has a known name that can be used in the subclass (@iv1). Now let's
look at a similar situation but where the superclass is one of the "fundamental"
classes pre-packaged with Ruby (i.e. Array, Hash, String, etc.). A "fundamental"
class is one that is not constructed from some other Ruby class using Ruby
source but is instead constructed from the same underlying machinery as the
interpreter itself (in the current implementation this means C source). In the
following "???" denotes a name for an instance variable in the superclass.

class C3 < Array
def initialize(inArray)
??? = inArray
end
def append(i)
??? << i << i
return(self)
end
def join(i)
out = ""
sep = "#" * i
???.each { |e| out << sep + e.to_s + sep }
return(out)
end
end

What do I use in place of the ???'s above? That is, what name do I use in the
subclass (C3) for the instance state of a fundamental superclass (Array)?

When a superclass is fundamental, can I access instance state in said superclass
without having to resort to the underlying C interface?

In my specific case, I am using instances of Array to hold data in a particular
format (the array elements are Hash's whose keys are String's of a particular
format and whose values are Hash's of a particular format). I want to subclass
Array, add a couple of methods, override a couple of methods, and also use the
non-overridden methods of Array.

It looks like I could make this work by simply adding my new methods directly to
Array and using alternate (if less descriptive) names for the Array methods I
was planning on overriding (this would allow me to access the internal state of
Array using self). However this approach will make the code slightly less
readable since some Array variables will be generic Array's and some will be my
special version. And to make things worse, I actually have two special versions
of Array and was planning on constructing two separate subclasses.

Thanx.

Jake


3 Answers

Brian Candler

5/8/2007 7:51:00 AM

0

On Tue, May 08, 2007 at 03:20:12PM +0900, xyz wrote:
> class C3 < Array
> def initialize(inArray)
> ??? = inArray
> end
> def append(i)
> ??? << i << i
> return(self)
> end
> def join(i)
> out = ""
> sep = "#" * i
> ???.each { |e| out << sep + e.to_s + sep }
> return(out)
> end
> end
>
> What do I use in place of the ???'s above? That is, what name do I use in the
> subclass (C3) for the instance state of a fundamental superclass (Array)?

self. An Array doesn't store its array in an instance variable; the object
*is* the array.

You can add instance variables in your subclass though.

You may find Array#replace useful, if you want to replace your array
contents with another array. (So 'self' still points to the same object of
course, but the array contents are different). This is almost the same as
having the array in @iv and then changing @iv to point to another array. The
difference is that if you had @iv, you could point it to some other object
which *isn't* an array.

> In my specific case, I am using instances of Array to hold data in a particular
> format (the array elements are Hash's whose keys are String's of a particular
> format and whose values are Hash's of a particular format). I want to subclass
> Array, add a couple of methods, override a couple of methods, and also use the
> non-overridden methods of Array.

Consider delegation instead of subclassing. In the long run it gives you
more flexibility.

Subclassing is the evil you learn from Object Oriented Programming courses.
It's taught so thoroughly that you come to believe that subclassing *is*
OOP. In fact, once you ditch subclassing, and worrying whether a Square is a
Rectangle or vice versa, life becomes much more straightforward :-)

Regards,

Brian.

Robert Klemme

5/8/2007 9:34:00 AM

0

On 08.05.2007 09:17, xyz wrote:
> In my specific case, I am using instances of Array to hold data in a particular
> format (the array elements are Hash's whose keys are String's of a particular
> format and whose values are Hash's of a particular format). I want to subclass
> Array, add a couple of methods, override a couple of methods, and also use the
> non-overridden methods of Array.

Please note that more often than not it is not a good idea to do this
(creating sub classes of core classes). Reason: you typically want some
specific operations on the content but if your class *is an* Array you
get all the Array manipulation methods unless you undefine or override
them. It's typically simpler and cleaner to just make your class *have
an* Array and only provide the interface to the public that you want to
allow.

Kind regards

robert

jeevan

5/9/2007 6:13:00 AM

0

Array.replace works (at least for my reasonably accurate test code).

i always wondered why Array, Hash, etc. had replace (which seemed superfluous
given that i can just do an assign). now i know at least one good reason why -
they effectively give one a channel to write the instance data of fundamental
classes.

and technically (speaking C here since that's what's currently under the hood),
self isn't the physical array, it's a pointer to an object struct containing an
RBasic struct, a pointer to an instance variable array (one of whose pointers
points to an RArray struct which contains the address of the physical array
storage and the length), and a pointer to the class struct, etc.

thanx again for the pointer :) to replace.

jake

"Brian Candler" <B.Candler@pobox.com> wrote in message
news:20070508075042.GA778@uk.tiscali.com...
> On Tue, May 08, 2007 at 03:20:12PM +0900, xyz wrote:
>> class C3 < Array
>> def initialize(inArray)
>> ??? = inArray
>> end
>> def append(i)
>> ??? << i << i
>> return(self)
>> end
>> def join(i)
>> out = ""
>> sep = "#" * i
>> ???.each { |e| out << sep + e.to_s + sep }
>> return(out)
>> end
>> end
>>
>> What do I use in place of the ???'s above? That is, what name do I use in the
>> subclass (C3) for the instance state of a fundamental superclass (Array)?
>
> self. An Array doesn't store its array in an instance variable; the object
> *is* the array.
>
> You can add instance variables in your subclass though.
>
> You may find Array#replace useful, if you want to replace your array
> contents with another array. (So 'self' still points to the same object of
> course, but the array contents are different). This is almost the same as
> having the array in @iv and then changing @iv to point to another array. The
> difference is that if you had @iv, you could point it to some other object
> which *isn't* an array.
>
>> In my specific case, I am using instances of Array to hold data in a
>> particular
>> format (the array elements are Hash's whose keys are String's of a particular
>> format and whose values are Hash's of a particular format). I want to
>> subclass
>> Array, add a couple of methods, override a couple of methods, and also use
>> the
>> non-overridden methods of Array.
>
> Consider delegation instead of subclassing. In the long run it gives you
> more flexibility.
>
> Subclassing is the evil you learn from Object Oriented Programming courses.
> It's taught so thoroughly that you come to believe that subclassing *is*
> OOP. In fact, once you ditch subclassing, and worrying whether a Square is a
> Rectangle or vice versa, life becomes much more straightforward :-)
>
> Regards,
>
> Brian.
>