As requested, here’s a FAQ question & answer on the usage of modules
and ‘include’
Q: As a creator of re-usable code, when should I use ‘module’ and
’include’?
useful way to ensure that your code is kept in its own separate
namespace. This ensures that the names you pick for your classes
won’t conflict with anyone else’s. An example:
module Foo
class Joy
def initialize(one, two)
puts "one: [#{one}] two: [#{two}]"
end
end
end
module Bar
class Joy
def initialize(something)
puts "Do #{something} already!"
end
end
end
In this case, you can’t write:
Joy.new(‘a’, ‘b’)
because there is no ‘Joy’ class in the current namespace. However,
you can write
Foo::Joy.new(‘a’, ‘b’)
or
Bar::Joy.new(‘a crossword puzzle’)
becuase Joy is defined in two different modules, Foo and Bar.
As a writer of modules or groups of closely related classes, you
probably want to surround your class definitions and globals with
’module’/‘end’, so that nobody will accidentally extend your class,
should they pick the same name as one of your classes.
But as a user of modules, you may get tired of typing the long
form. One option is to use an alias:
Joy = Foo::Joy
Then you can just use the short form:
Joy.new(‘a’, ‘b’);
Another option is to use the ‘include’ method:
include Foo
lets you just use ‘Joy’ instead of Foo::Joy, just as
include Bar
lets you just use ‘Joy’ instead of Bar::Joy
However, if you have both ‘include’ statements, then ‘Joy’ will
refer to the last unique reference it could be. That is, if you
wrote:
include Foo;
include Bar;
then ‘Joy’ would refer to Bar::Joy. If you wrote:
include Foo:
again, then ‘Joy’ would STILL refer to Bar::Joy.
All this takes effect in the most restrictive lexical scope
available. If you do this inside a class definition, only that
class will be able to use the short forms. If you do it inside
another module definition, the entire module can use those short
forms. [ true? false? I’m not sure about this one. – eric ] If
you do it at the top of a file, everything in that file can use the
short forms.
modules can also be used to implement ‘mixins’. A ‘mixin’ is
logically nothing more than a group of functions that are grouped
inside a module directly, not in any class definition. A
pseudo-definition of the Comparable mixin might illustrate the idea
well:
module Comparable
def between?(min,max)
#insert code here
end
def <(other)
return 1 if ((self <=> other) < 0)
return 0
end
… and so on
end
To make your class Comparable, just
class MyClass
include Comparable
end
This gives you access to all the functions defined in the Comparable
module, without having to refer to them all as Comparable::<(other),
and so forth. Mixins are really a very simple concept, but can have
very powerful applications, and can give an effect similar to
multiple inheritance without actually providing that facility.
Questions? Comments? I’m still quite new to Ruby, but this seems to
do the trick for me, at the risk of being overly verbose.
-=Eric
···
A: Surrounding your class definitions with “module Foo”/“end” is a
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
– Blair Houghton