At Well House Consultants, we provide
training courses on
subjects such as Perl, Python, Tcl/Tk, PHP and MySQL. We're asked (and answer)
many questions, and answers to those which are of general interest are
published in this area of our site.
>> link to
our solutions centre home page
>> link to
Ruby - Classes and Objects>> link to
Ruby - More Classes and Objects>> link to
resource index - Ruby
WHY USE OBJECTS IN RUBY ANYWAY?
Single block code is great for short utility scripts, but as
coding requirements grow you'll do better to move to a more
structured approach, with named blocks of code ('methods'
in Ruby) which will perhaps be spread around a number of
files.
With further growth, an Object Oriented approach becomes
much more logical; with OO, you can bind a method to an
object or type of object, and then call up the method as
appropriate. In other words, you can have several methods
called 'length' - one of which returns the length of a
cricket pitch, and another the length of a TV program.
They'll work differently inside, but you ruby program will
know which one to run when - the length of "The Oval" is
clearly the length of a cricket pitch, and the length of
"Emmerdale" is almost certainly half an hour!
Ruby's OO model is superb. It's pure, robust, trusting and
not overcomplex as you'll learn in this module and beyond
DEFINING A CLASS
You define a class with a class statement, through to a
nested end statement. Your class definition will contain
methods to work on objects (class members) which are defined
with defs, each also ending with an end.
A method called initialize is your constructor - in other
words, you write a method called initialize which defines
how you create an object in the first place.
Variables with names starting with an @ within your method
definitions are instance variables. In other words, if you
start a variable name with an @ you're saying that you're
sharing that variable with all the other methods that you've
def'd in the class, BUT that there's a different variable
(of the same name) for each case (instance) of the class.
The variable "name" and "@name" are different - "name" is
local to the current closure (you'll hear that word come up
many times more), but "@name" applies to the current object;
you may have used the word "this" or "self" to indicate the
same thing in other programming languages. And, yes, you
CAN have a variable called name and a variable called @name
at the same time, pointing to different locations in memory
and containing different information - and even different
types of object.
By defining a class, you are NOT using it! You are simple
saying what it would do IF you chose to use it ... which
you'll probably do later in your code. After all, there
would be no point in defining something just to have the
definition go away when your program terminated.
Example: Defining a type of object called "person":
class Person
# Constructor - called 'initialize'.
# Variables with leading @ are instance (object) variables
def initialize(name = "Mate")
@name = name
end
# methods to run on Person object
def aussie
print "Wotcha, #{@name}\n"
end
def usa
print "Hi, #{@name}\n"
end
end
MAKING USE OF A CLASS
Having defined a class, we need to make use of it. Use the
new keyword/method to create object(s) (instances) of the
class. This keyword causes the initialize method to be
run. A reference to the newly created object is returned,
which you can store in a variable (you can also do other
things with it!).
Once you have created an object, you can run other methods
that are available to members of that class on it.
Let's take our Person class, and create two people and greet
them in Australia and in the USA:
starter = Person.new
starter.aussie
nextperson = Person.new("Betty")
nextperson.usa
nextperson.aussie
When we run that, we get:
earth-wind-and-fire:~/ruby/r105 grahamellis$ ruby myo.rb
Wotcha, Mate
Hi, Betty
Wotcha, Betty
earth-wind-and-fire:~/ruby/r105 grahamellis$
LOADING A CLASS FROM ELSEWHERE
You'll want to share your classes (and other code too) from
other files, which you can do with a require.
Your main code looks like:
require "dp"
starter = Person.new
starter.aussie
starter.britain
nextperson = Person.new("Percy")
nextperson.usa
nextperson.aussie
and that will load (and evaluate - i.e. run) the file dp.rb
when it executes the require statement.
We have the following in the dp.rb file:
class Person
def initialize(name = "friend")
@name = name
end
def aussie
print "Wotcha, #{@name}\n"
end
def usa
print "Hi, #{@name}\n"
end
def britain
print "Hello, #{@name}\n"
end
end
Other subjects that we'll look at later are: include, load,
and specifying which directory the extensions are brought in
from.
See also
Well House Consultants provides training courses ... that's our main business ...
and from time to time we write additional technical notes and articles to widen
the issues covered for a particular group of trainees. Longer articles of more
general interest are published here in our
solutions centre.
You'll also find shorter items at
The Horse's Mouth and
delegate's questions answered at
the Opentalk forum.