Q: inheriting from Array, overloading []

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.

Hi,

···

In message "Re: Q: inheriting from Array, overloading " on Thu, 30 Jun 2005 10:05:43 +0900, Matt C <canimal@invalid.com> writes:

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.

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

Devin Mullins <twifkak@comcast.net> wrote in news:42C34B5F.3050300
@comcast.net:

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

Matt C wrote:

Devin Mullins <twifkak@comcast.net> wrote in news:42C34B5F.3050300
@comcast.net:

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

:slight_smile:

Kind regards

    robert

"Robert Klemme" <bob.news@gmx.net> wrote in news:3ii7agFl8o74U1
@individual.net:

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

:slight_smile:

Kind regards

    robert

Whoops! Thanks.

Matt