# Subclassing fundamental classes

**URL:** <https://www.ruby-forum.com/t/subclassing-fundamental-classes/103596>\
**Category:** Ruby\
**Created:** [May 8, 2007, 8:21am UTC](https://www.ruby-forum.com/t/subclassing-fundamental-classes/103596 "2007-05-08T08:21:49Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![xyz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/b5a626/32.png) [@xyz](https://www.ruby-forum.com/u/xyz)\
**Post date:** [May 8, 2007, 8:21am UTC](https://www.ruby-forum.com/t/subclassing-fundamental-classes/103596/1 "2007-05-08T08:21:49Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![xyz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/b5a626/32.png) [@xyz](https://www.ruby-forum.com/u/xyz)\
**Post date:** [May 8, 2007, 8:35am UTC](https://www.ruby-forum.com/t/subclassing-fundamental-classes/103596/2 "2007-05-08T08:35:49Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![xyz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/b5a626/32.png) [@xyz](https://www.ruby-forum.com/u/xyz)\
**Post date:** [May 8, 2007, 11:35am UTC](https://www.ruby-forum.com/t/subclassing-fundamental-classes/103596/3 "2007-05-08T11:35:52Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![xyz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/b5a626/32.png) [@xyz](https://www.ruby-forum.com/u/xyz)\
**Post date:** [May 9, 2007, 7:15am UTC](https://www.ruby-forum.com/t/subclassing-fundamental-classes/103596/4 "2007-05-09T07:15:35Z")

</div>

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 C.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote in message  
news:removed\_email\_address@domain.invalid…

---

<div class="post-metadata">

**Author:** ![xyz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/b5a626/32.png) [@xyz](https://www.ruby-forum.com/u/xyz)\
**Post date:** [May 8, 2007, 9:51am UTC](https://www.ruby-forum.com/t/subclassing-fundamental-classes/103596/5 "2007-05-08T09:51:56Z")

</div>

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 🙂

Regards,

Brian.
