As you start to write bigger and bigger Ruby programs, you'll
naturally find yourself producing chunks of reusable code---libraries
of related routines that are generally applicable. You'll want to
break this code out into separate files so the contents can be shared
among different Ruby programs.
Often this code will be organized into classes, so you'll probably
stick a class (or a set of interrelated classes) into a file.
However, there are times when you want to group things together that
don't naturally form a class.
An initial approach might be to put all these things into a file and
simply load that file into any program that needs it. This is the
way the C language works. However, there's a problem. Say you write a
set of trigonometry functions
sin
,
cos
, and so on.
You stuff them all into a file,
trig.rb
, for future generations
to enjoy. Meanwhile, Sally is working on a simulation of good and evil,
and codes up a set of her own useful routines, including
beGood
and
sin
, and sticks them into
action.rb
. Joe, who
wants to write a program to find out how many angels can dance on the
head of a pin, needs to load both
trig.rb
and
action.rb
into his program. But both define a method called
sin
. Bad news.
The answer is the module mechanism. Modules define a namespace, a
sandbox in which your methods and constants can play without having to
worry about being stepped on by other methods and constants. The trig
functions can go into one module:
module Trig
PI = 3.141592654
def Trig.sin(x)
# ..
end
def Trig.cos(x)
# ..
end
end
|
and the good and bad action methods can go into another:
module Action
VERY_BAD = 0
BAD = 1
def Action.sin(badness)
# ...
end
end
|
Module constants are named just like class constants, with an initial
uppercase letter.
The method definitions look similar, too: these
module methods are defined just like class methods.
If a third program wants to use these modules, it can simply load up
the two files (using the Ruby
require
statement, which we discuss
on page 103) and reference the qualified names.
require "trig"
require "action"
y = Trig.sin(Trig::PI/4)
wrongdoing = Action.sin(Action::VERY_BAD)
|
As with class methods, you call a module method by preceding its name
with the module's name and a period, and you reference a constant
using the module name and two colons.