Q: inheriting from Array, overloading []

M

Matt C

New to Ruby. Probably my terminology will be a bit off.

In the Pickaxe book (first edition) they show a clever little trick with
the SongList class, where you can use [] to pull a song from the list using
either the integer index or the name of the song.

I wanted to try something like that, but with a subclass of Array rather
than writing a wrapper around an array. I had the idea I might be able to
use super:

class TalkerArray < Array #will hold a collection of Talkers.

def [](key)
if key.kind_of?(Integer)
return super[key]
else
return self.find{|t| t.name = key} #talkers have .name property.
end
end

end

but it didn't work (*). I bet there is a simple way to make something like
this work while inheriting from Array, though. Can anyone show me?

Thanks,
Matt



*: The error message I got was strange:

E:/matt/ruby/usr/ww/chat.rb:173:in `[]': undefined method `[]' for #
<Talker:0x2a5be68 @name="bob", @last_msg=0> (NoMethodError)

Why the heck is it looking at the Talker object? I must not understand
what 'super' does. Anyway, I put this as a postscript because it's kind of
a side issue for me. I'm guessing I don't really need 'super', or
understanding 'super', to override [] the way I want to. So I can worry
about that some other day. Which is not to say I won't listen if someone
wants to explain, it's just not my priority of the moment. Ok, really
done typing now.
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Q: inheriting from Array, overloading []"

|class TalkerArray < Array #will hold a collection of Talkers.
|
| def [](key)
| if key.kind_of?(Integer)
| return super[key]
| else
| return self.find{|t| t.name = key} #talkers have .name property.
| end
| end
|
|end

super[key] means (super(key)[key]).

matz.
 
D

Devin Mullins

Change super[key] to super(key) or super key. Remember, [] is just
another method, and like other methods, it accepts the typical form.

class A
def [](key)
puts "key: #{key}"
end
end

a = A.new
a.[](5)

Outputs:
key: 5

As matz posted, super defaults to passing the same values passed to you,
while super() passes zero args.

class A
def put(a)
puts a
end
end
class B<A
def put(n)
if n == 0
super "zero"
elsif n < 0
super()
else
super
end
end
end
b = B.new
b.put 0
b.put 5
b.put -1

Outputs:
zero
5
-:11:in `put': wrong number of arguments (0 for 1) (ArgumentError)
from -:11:in `put'
from -:20

So your code was invoking the super method with key as a parameter,
taking the return value, and then invoking #[](key) on that.

Devin
 
M

Matt C

Change super[key] to super(key) or super key. Remember, [] is just
another method, and like other methods, it accepts the typical form. ....
So your code was invoking the super method with key as a parameter,
taking the return value, and then invoking #[](key) on that.

Devin

It took me a little while, but I get it now. It all comes together. Very
useful example.

Thanks to both of you.

Matt
 
R

Robert Klemme

Matt said:
Change super[key] to super(key) or super key. Remember, [] is just
another method, and like other methods, it accepts the typical form.
... So your code was invoking the super method with key as a
parameter, taking the return value, and then invoking #[](key) on
that.

Devin

It took me a little while, but I get it now. It all comes together.
Very useful example.

Thanks to both of you.

Matt

There is also a spelling error - compare these:

return self.find{|t| t.name = key} # original
return self.find{|t| t.name == key} # fake - but better

:)

Kind regards

robert
 
M

Matt C

There is also a spelling error - compare these:

return self.find{|t| t.name = key} # original
return self.find{|t| t.name == key} # fake - but better

:)

Kind regards

robert

Whoops! Thanks.

Matt
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,197
Latest member
ScottChare

Latest Threads

Top