From: Eric Schwartz Date: 2002-11-09T11:35:50+09:00 Subject: [FAQ] Why use 'include' 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'? A: Surrounding your class definitions with "module Foo"/"end" is a 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 -- Come to think of it, there are already a million monkeys on a million typewriters, and Usenet is NOTHING like Shakespeare. -- Blair Houghton