[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Inheriting Array and slice() behaviour

Sylvain Joyeux

7/6/2005 9:17:00 AM

I have a class inheriting Array, and I expected slice() and []
to return Array objects. Unfortunately

irb(main):001:0> class Expression < Array
irb(main):002:1> end
=> nil
irb(main):003:0> test = Expression.new
=> []
irb(main):004:0> test.concat( (1..10).to_a )
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):005:0> test.slice(1..5)
=> [2, 3, 4, 5, 6]
irb(main):006:0> test.slice(1..5).class
=> Expression

And I don't understand why ...
Moreover, since my Expression class has instance variables, the instance
produced by slice() does not have it anymore (which is bad)

I wokarounded this by using Delegator
Any idea on why this behaviour ?

Sylvain



42 Answers

William Morgan

7/6/2005 4:06:00 PM

0

Excerpts from Sylvain Joyeux's mail of 6 Jul 2005 (EDT):
> I have a class inheriting Array, and I expected slice() and []
> to return Array objects. Unfortunately
[...]
> Moreover, since my Expression class has instance variables, the instance
> produced by slice() does not have it anymore (which is bad)

It looks like [], slice and slice! methods create a new instance of the
objects class as the return value, but don't initialize it---so any
instance variables will be nil (rb_ary_subseq). I agree that this is
weird.

> I wokarounded this by using Delegator

What return type do you want? Arrays or Expressions? You can force
return values back to Arrays with #to_a, or manually make Expressions
with something like

y = Expression.new(x.slice(1..5).to_a)

--
William <wmorgan-ruby-talk@masanjin.net>


Sylvain Joyeux

7/6/2005 4:13:00 PM

0

> What return type do you want? Arrays or Expressions? You can force
> return values back to Arrays with #to_a, or manually make Expressions
> with something like
>
> y = Expression.new(x.slice(1..5).to_a)

I find it VERY weird to build anything else than an Array here. Array now
nothing about Expression, so I don't see how - in general - it could build
a well-formed Expression object

Sylvain


dblack

7/6/2005 4:25:00 PM

0

Daniel Brockman

7/6/2005 4:26:00 PM

0

William Morgan

7/6/2005 4:58:00 PM

0

Excerpts from Sylvain Joyeux's mail of 6 Jul 2005 (EDT):
> > What return type do you want? Arrays or Expressions? You can force
> > return values back to Arrays with #to_a, or manually make
> > Expressions with something like
> >
> > y = Expression.new(x.slice(1..5).to_a)
>
> I find it VERY weird to build anything else than an Array here. Array
> now nothing about Expression, so I don't see how - in general - it
> could build a well-formed Expression object

I agree with you. I think this is bad behavior.

--
William <wmorgan-ruby-talk@masanjin.net>


Yukihiro Matsumoto

7/6/2005 5:20:00 PM

0

Hi,

In message "Re: Inheriting Array and slice() behaviour"
on Wed, 6 Jul 2005 18:17:21 +0900, Sylvain Joyeux <sylvain.joyeux@polytechnique.org> writes:

|I have a class inheriting Array, and I expected slice() and []
|to return Array objects.

Why? I'd expect them to return instances of the class of the
receiver, as Daniel does in [ruby-talk:147323], since they are ripped
part of the receiver.

|Moreover, since my Expression class has instance variables, the instance
|produced by slice() does not have it anymore (which is bad)

I agree that is bad. It might be possible to call initialize() at the
time of sub-array allocation, at the cost of performance. Besides
that, we have to make consensus for how initialize() will be called
for those sub-array.

Anyway, I'd suggest you not to subclass basic classes, unless you are
sure what you're doing. I don't think Expressions by no means have
is-a relationship to Arrays. Inheritance is not a panacea.

matz.


Ara.T.Howard

7/6/2005 6:14:00 PM

0

Sylvain Joyeux

7/6/2005 8:02:00 PM

0

This is a lisp-like language, so expressions are basically array of atoms
and expressions. When I do a slice() this is to get a subset of the list,
but a subset is not an expression itself.

Expression is-a Array, but Expression.slice is just an Array

Sylvain



Ara.T.Howard

7/6/2005 9:26:00 PM

0

Robert Klemme

7/6/2005 9:31:00 PM

0

William Morgan <wmorgan-ruby-talk@masanjin.net> wrote:
> Excerpts from Sylvain Joyeux's mail of 6 Jul 2005 (EDT):
>>> What return type do you want? Arrays or Expressions? You can force
>>> return values back to Arrays with #to_a, or manually make
>>> Expressions with something like
>>>
>>> y = Expression.new(x.slice(1..5).to_a)
>>
>> I find it VERY weird to build anything else than an Array here. Array
>> now nothing about Expression, so I don't see how - in general - it
>> could build a well-formed Expression object
>
> I agree with you. I think this is bad behavior.

I wouldn't be so certain of this. It's normal for operations like #dup and
#clone to behave that way. Also, part of the smartness of ruby is that you
can simply do self.class.new to get a new instance of the same class. And
often you need to create an instance of the same class. That's not too
abnormal.

IMHO if there is a problem then with proper initialization of the new
instance. OTOH, inheriting classes like Array is seldom really good. There
are too many methods that return plain arrays and you end up with Arrays
anyway. Delegation, ad hoc modification or extension with a Module is often
better.

Kind regards

robert