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

Classes, Objects, and Variables



From the examples we've shown so far, you might be wondering about our earlier assertion that Ruby is an object-oriented language. Well, this chapter is where we justify that claim. We're going to be looking at how you create classes and objects in Ruby, and at some of the ways in which Ruby is more powerful than most object-oriented languages. Along the way, we'll be implementing part of our next billion-dollar product, the Internet Enabled Jazz and Blue Grass jukebox.

After months of work, our highly paid Research and Development folks have determined that our jukebox needs songs. So it seems like a good idea to start off by setting up a Ruby class that represents things that are songs. We know that a real song has a name, an artist, and a duration, so we'll want to make sure that the song objects in our program do, too.

We'll start off by creating a basic class Song,[As we mentioned on page 9, class names start with an uppercase letter, while method names start with a lowercase letter.] which contains just a single method, initialize.

class Song
  def initialize(name, artist, duration)
    @name     = name
    @artist   = artist
    @duration = duration
  end
end

initialize is a special method in Ruby programs. When you call Song.new to create a new Song object, Ruby creates an uninitialized object and then calls that object's initialize method, passing in any parameters that were passed to new. This gives you a chance to write code that sets up your object's state.

For class Song, the initialize method takes three parameters. These parameters act just like local variables within the method, so they follow the local variable naming convention of starting with a lowercase letter.

Each object represents its own song, so we need each of our Song objects to carry around its own song name, artist, and duration. This means we need to store these values as instance variables within the object. In Ruby, an instance variable is simply a name preceded by an ``at'' sign (``@''). In our example, the parameter name is assigned to the instance variable @name, artist is assigned to @artist, and duration (the length of the song in seconds) is assigned to @duration.

Let's test our spiffy new class.

aSong = Song.new("Bicylops", "Fleck", 260)
aSong.inspect "#<Song:0x401b4924 @duration=260, @artist=\"Fleck\", @name=\"Bicylops\">"

Well, it seems to work. By default, the inspect message, which can be sent to any object, dumps out the object's id and instance variables. It looks as though we have them set up correctly.

Our experience tells us that during development we'll be printing out the contents of a Song object many times, and inspect's default formatting leaves something to be desired. Fortunately, Ruby has a standard message, to_s, which it sends to any object it wants to render as a string. Let's try it on our song.

aSong = Song.new("Bicylops", "Fleck", 260)
aSong.to_s "#<Song:0x401b499c>"

That wasn't too useful---it just reported the object id. So, let's override to_s in our class. As we do this, we should also take a moment to talk about how we're showing the class definitions in this book.

In Ruby, classes are never closed: you can always add methods to an existing class. This applies to the classes you write as well as the standard, built-in classes. All you have to do is open up a class definition for an existing class, and the new contents you specify will be added to whatever's there.

This is great for our purposes. As we go through this chapter, adding features to our classes, we'll show just the class definitions for the new methods; the old ones will still be there. It saves us having to repeat redundant stuff in each example. Obviously, though, if you were creating this code from scratch, you'd probably just throw all the methods into a single class definition.

Enough detail! Let's get back to adding a to_s method to our Song class.

class Song
  def to_s
    "Song: #{@name}--#{@artist} (#{@duration})"
  end
end
aSong = Song.new("Bicylops", "Fleck", 260)
aSong.to_s "Song: Bicylops--Fleck (260)"

Excellent, we're making progress. However, we've slipped in something subtle. We said that Ruby supports to_s for all objects, but we didn't say how. The answer has to do with inheritance, subclassing, and how Ruby determines what method to run when you send a message to an object. This is a subject for a new section, so....
Ruby Programming
Previous Page Home Next Page

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