[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’?

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

Eric Schwartz emschwar@fc.hp.com writes:

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’?

Excellent job! I’ve put this on
http://www.rubygarden.org/iowa/faqtotum.

modules can also be used to implement ‘mixins’. A ‘mixin’ is

I didn’t include this part because there is something similar already.

YS.

As requested, here’s a FAQ question & answer on the usage of modules and
‘include’

Whoa, I really like this. It would be nice to more of this type of FAQ.
Thanks!

  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.

Well, I've not understood what you are trying to say. Can you explain what
is "the most restrictive lexical scope available" ?

pigeon% cat c.rb
module M
   class A
   end
end

include M
pigeon%

pigeon% cat b.rb
#!/usr/bin/ruby
require 'c'
p A.new
pigeon%

pigeon% b.rb
#<M::a:0x401ad860>
pigeon%

Guy Decoux

The Perl newsgroup has FAQ postings on all the FAQ topics. I think it is a
great idea to start it in the Ruby group as well.

Just great, Eric. Thanks!

Massimiliano

···

On Sat, Nov 09, 2002 at 11:35:50AM +0900, Eric Schwartz wrote:

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.

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:

[about 70 lines snipped ;]

Let me add to the chorus of praise :slight_smile: We may have a FAQ book out in no time!

Gavin

···

From: “Eric Schwartz” emschwar@fc.hp.com

Well, A.new is still an M::A, but it’s just been made part of the
object’s current lexical scope. At least that’s how I interpret the
statement.

-austin
– Austin Ziegler, austin@halostatue.ca on 2002.11.09 at 09.35.24

···

On Sat, 9 Nov 2002 20:12:57 +0900, ts wrote:

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. If you do it at the top of a file, everything in that
file can use the short forms.
Well, I’ve not understood what you are trying to say. Can you
explain what is “the most restrictive lexical scope available” ?

pigeon% cat c.rb
module M
class A; end
end

include M

pigeon% cat b.rb
#!/usr/bin/ruby
require ‘c’
p A.new

pigeon% b.rb
#<M::a:0x401ad860>

ts decoux@moulon.inra.fr writes:

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.

Well, I’ve not understood what you are trying to say. Can you explain what
is “the most restrictive lexical scope available” ?

That would be the tightest scope that applies. If you ‘include’ a
module from inside a method, then you could only use the short forms
inside the method’s definition. If you do so inside a class, you can
only use the short forms inside that class’ scope (which is how
mixins work). include’ing inside a module gives that entire module
access to those short names, and so on. I think I may want to rewrite
that bit to talk about namespaces, instead of lexical scopes, though.

pigeon% cat c.rb
module M
class A
end
end

include M
pigeon%

pigeon% cat b.rb
#!/usr/bin/ruby
require ‘c’
p A.new
pigeon%

pigeon% b.rb
#<M::a:0x401ad860>
pigeon%

I’m not sure what this example is intended to illustrate. It
certainly matches up with what I wrote. When the “require ‘c’” code
is executed, it loads c.rb. The last statement of c.rb is ‘include
M’, which means that anybody 'require’ing c.rb will automatically
import all the classes and methods (and variables) of module M into
its current namespace. (Which I tried to indicate is often a bad
idea, as a module writer.)

-=Eric

···


Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
– Blair Houghton

Well, A.new is still an M::A, but it's just been made part of the
object's current lexical scope. At least that's how I interpret the
statement.

Well, my example was for this :

forms. If you do it at the top of a file, everything in that
file can use the short forms.

Strange but for me

        "the most restrictive lexical scope available"

make me think to a P language :-(((

Guy Decoux

Actually, the problem I think Guy had with the way it was written
was that it was “file”-based; his example shows that it’s more
object-scope based over file-based.

-austin
– Austin Ziegler, austin@halostatue.ca on 2002.11.11 at 14.57.28

···

On Tue, 12 Nov 2002 04:26:42 +0900, Eric Schwartz wrote:

I’m not sure what this example is intended to illustrate. It
certainly matches up with what I wrote. When the “require ‘c’”
code is executed, it loads c.rb. The last statement of c.rb is
‘include M’, which means that anybody 'require’ing c.rb will
automatically import all the classes and methods (and variables)
of module M into its current namespace. (Which I tried to indicate
is often a bad idea, as a module writer.)

I'm not sure what this example is intended to illustrate. It
certainly matches up with what I wrote. When the "require 'c'" code
is executed, it loads c.rb. The last statement of c.rb is 'include
M', which means that anybody 'require'ing c.rb will automatically
import all the classes and methods (and variables) of module M into
its current namespace. (Which I tried to indicate is often a bad
idea, as a module writer.)

Well, sorry to say this but I hope that someone will correct this FAQ (not
really important for me, because it's just for "anglois" :-))

Guy Decoux

ts decoux@moulon.inra.fr writes:

Well, A.new is still an M::A, but it’s just been made part of the
object’s current lexical scope. At least that’s how I interpret the
statement.

Well, my example was for this :

forms. If you do it at the top of a file, everything in that
file can use the short forms.

Yes, but you’ve effectively done it at the top of every file that
'require’s c.rb, by putting the ‘include’ at the end of that file.

Strange but for me

    "the most restrictive lexical scope available"

make me think to a P language :-(((

I should have said “the most restrictive namespace available”, but I’m
not too clear on how Ruby’s concept of namespaces maps to mine.

-=Eric

···


Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
– Blair Houghton