On Thu, Mar 01, 2007 at 09:15:40PM +0900, Dick wrote:
> I am new to Ruby.  This is the very first class I am writing and it
> doesn't seem that Ruby is designed to handle what I thought should work.
> Why doesn't the below work?
> 
> class Song < ActiveRecord::Base
>   @@dcounts = []
> 
>   def Song.count(difficulty, artistid)
>     @@dcounts[difficulty][artistid]
>   end
> 
>   def Song.count=(difficulty, artistid, val)
>     @@dcounts[difficulty] ||= {}
>     @@dcounts[difficulty][artistid] = val
>   end
> end
> 
> Song.count(1, 3547) = 10
> 
> test.rb:14: parse error, unexpected '=', expecting $
> Song.count(1,3547) = 10
>                     ^

Unfortunately, a 'foo=' method can only take one argument, which is the
expression to the right of the equals sign.

You can create a regular method, e.g.

  def Song.set_difficulty(difficulty, artistid, val)
  ...
  Song.set_difficultly(1, 3547, 10)

However I wonder if perhaps you're going about this the wrong way. You're
using a class variable, @@dcounts, which implies that you plan to create
multiple instances of class 'Song'. So maybe what you really need is an
accessor on the individual Song object to set its difficulty, which could
also update your @@dcounts index for you.

Also, consider having a separate SongIndex class, to which individual Songs
are added. At the time when you add them (or at some later time) you can
index its difficulty.

This approach is cleaner because you get away from the class variable; you
can just use a regular instance variable of the SongIndex class. It is also
more flexible - it allows you to create individual instances of Song which
are not in the global index.

HTH,

Brian.