Let's say it again. Ruby is a genuine object-oriented language.
Everything you manipulate is an object, and the results of those
manipulations are themselves objects. However, many languages make the
same claim, and they often have a different interpretation of what
object-oriented means and a different terminology for the concepts
So, before we get too far into the details, let's briefly look at the
terms and notation that we'll
When you write object-oriented code, you're normally looking to model
concepts from the real world in your code. Typically during this modeling
process you'll discover categories of things that need to be
represented in code. In a jukebox, the concept of a ``song'' might be
such a category. In Ruby, you'd define a class
each of these entities. A class is a combination of state (for
example, the name of the song) and methods that use that state (perhaps
a method to play the song).
Once you have these classes, you'll typically want to create a number
of each. For the jukebox system containing a class
, you'd have separate instances for popular hits such
as ``Ruby Tuesday,'' ``Enveloped in Python,'' ``String of Pearls,''
``Small talk,'' and so on. The word object
interchangeably with class instance (and being lazy typists, we'll
probably be using the word ``object'' more frequently).
In Ruby, these objects are created by calling a constructor, a special
method associated with a class. The standard constructor is called
song1 = Song.new("Ruby Tuesday")
song2 = Song.new("Enveloped in Python")
# and so on
These instances are both derived from the same class, but they have
unique characteristics. First, every object has a unique object
(abbreviated as object id
). Second, you can
define instance variables
variables with values that are
unique to each instance. These instance variables hold an object's
state. Each of our songs, for example, will probably have an instance
variable that holds the song title.
Within each class, you can define instance methods
is a chunk of functionality which may be called from within the class
and (depending on accessibility constraints) from outside. These
instance methods in turn have access to the object's instance
variables, and hence to the object's state.
Methods are invoked by sending a message to an object.
contains the method's name, along with any parameters the method may
need.[This idea of expressing method calls in the form of
messages comes from Smalltalk.]
When an object receives a message,
it looks into its own class for a corresponding method. If found, that
method is executed. If the method isn't
found, ... well,
we'll get to that later.
This business of methods and messages may sound complicated, but in
practice it is very natural. Let's look at some method calls.
(Remember that the arrows in the code examples show the values
returned by the corresponding expressions.)
"duh dum, da dum de dum ..."
Here, the thing before the period is called the receiver
the name after the period is the method to be invoked.
example asks a string for its length, and the second asks a different
string to find the index of the letter ``c.'' The third line has a
number calculate its absolute value. Finally, we ask Sam to play us
It's worth noting here a major difference between Ruby and most other
languages. In (say) Java, you'd find the absolute value of some number
by calling a separate function and passing in that number. You might
number = Math.abs(number) // Java code
In Ruby, the ability to determine an absolute value is built into
numbers---they take care of the details internally. You simply send
to a number object and let it do the work.
The same applies to all Ruby objects: in C you'd write
, while in Ruby it's
, and so
on. This is part of what we mean when we say that Ruby is a genuine OO