Subclassing fundamental classes

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

xyz wrote:

     return(self)

  #------------------------- 

classes pre-packaged with Ruby (i.e. Array, Hash, String, etc.). A “fundamental”
??? << i << i
What do I use in place of the ???'s above? That is, what name do I use in the

Jake

I think it’s just “self”, but you’ll have one problem because you can’t
assign a value to self. I would try:

    def initialize(inArray)
       inArray.each {|elem| self << elem}
    end

Dan

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

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 :slight_smile: to replace.

jake

“Brian C.” [email protected] wrote in message
news:[email protected]

On Tue, May 08, 2007 at 03:20:12PM +0900, xyz wrote:

     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 :slight_smile:

Regards,

Brian.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs