Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

  




 

 

Ruby Programming
Previous Page Home Next Page

Implementing a SongList Container

After that little diversion into arrays and hashes, we're now ready to implement the jukebox's SongList. Let's invent a basic list of methods we need in our SongList. We'll want to add to it as we go along, but it will do for now.

append( aSong ) � list
Append the given song to the list.
deleteFirst() � aSong
Remove the first song from the list, returning that song.
deleteLast() � aSong
Remove the last song from the list, returning that song.
[ anIndex } � aSong
Return the song identified by anIndex, which may be an integer index or a song title.

This list gives us a clue to the implementation. The ability to append songs at the end, and remove them from both the front and end, suggests a dequeue---a double-ended queue---which we know we can implement using an Array. Similarly, the ability to return a song at an integer position in the list is supported by arrays.

However, there's also the need to be able to retrieve songs by title, which might suggest using a hash, with the title as a key and the song as a value. Could we use a hash? Well, possibly, but there are problems. First a hash is unordered, so we'd probably need to use an ancillary array to keep track of the list. A bigger problem is that a hash does not support multiple keys with the same value. That would be a problem for our playlist, where the same song might be queued up for playing multiple times. So, for now we'll stick with an array of songs, searching it for titles when needed. If this becomes a performance bottleneck, we can always add some kind of hash-based lookup later.

We'll start our class with a basic initialize method, which creates the Array we'll use to hold the songs and stores a reference to it in the instance variable @songs.

class SongList
  def initialize
    @songs = Array.new
  end
end

The SongList#append method adds the given song to the end of the @songs array. It also returns self, a reference to the current SongList object. This is a useful convention, as it lets us chain together multiple calls to append. We'll see an example of this later.

class SongList
  def append(aSong)
    @songs.push(aSong)
    self
  end
end

Then we'll add the deleteFirst and deleteLast methods, trivially implemented using Array#shift and Array#pop , respectively.

class SongList
  def deleteFirst
    @songs.shift
  end
  def deleteLast
    @songs.pop
  end
end

At this point, a quick test might be in order. First, we'll append four songs to the list. Just to show off, we'll use the fact that append returns the SongList object to chain together these method calls.

list = SongList.new
list.
  append(Song.new('title1', 'artist1', 1)).
  append(Song.new('title2', 'artist2', 2)).
  append(Song.new('title3', 'artist3', 3)).
  append(Song.new('title4', 'artist4', 4))

Then we'll check that songs are taken from the start and end of the list correctly, and that nil is returned when the list becomes empty.

list.deleteFirst Song: title1--artist1 (1)
list.deleteFirst Song: title2--artist2 (2)
list.deleteLast Song: title4--artist4 (4)
list.deleteLast Song: title3--artist3 (3)
list.deleteLast nil

So far so good. Our next method is [], which accesses elements by index. If the index is a number (which we check using Object#kind_of? ), we just return the element at that position.

class SongList
  def [](key)
    if key.kind_of?(Integer)
      @songs[key]
    else
      # ...
    end
  end
end

Again, testing this is pretty trivial.

list[0] Song: title1--artist1 (1)
list[2] Song: title3--artist3 (3)
list[9] nil

Now we need to add the facility that lets us look up a song by title. This is going to involve scanning through the songs in the list, checking the title of each. To do this, we first need to spend a
Ruby Programming
Previous Page Home Next Page

 
 
  Published under the terms of the Open Publication License Design by Interspire