Including a module in an included module.

P

Prince Nez

module M1; end
module M2; include M1; end
module M1; DOG = :woof; end
module M2; DOG; end
# => :woof

I can add to a module after it has been included. Neat.

module M1; DOG = :woof; end
module M2; include M1; end
module M3; include M2; end
module M3; DOG; end
# => :woof

Including a module seems to give me any modules that it includes. Swish.

module M2; end
module M3; include M2; end
module M1; DOG = :woof; end
module M2; include M1; end
module M3; DOG; end
# => NameError: uninitialized constant M3::DOG

So I assumed I'd be able to include a module in a module after it has
been included, if you get my drift. It surprises me that this dog
doesn't bark.
 
7

7stud --

Prince said:
module M1; end
module M2; include M1; end
module M1; DOG = :woof; end
module M2; DOG; end
# => :woof

I can add to a module after it has been included. Neat.

module M1; DOG = :woof; end
module M2; include M1; end
module M3; include M2; end
module M3; DOG; end
# => :woof

Including a module seems to give me any modules that it includes. Swish.

module M2; end
module M3; include M2; end
module M1; DOG = :woof; end
module M2; include M1; end
module M3; DOG; end
# => NameError: uninitialized constant M3::DOG

So I assumed I'd be able to include a module in a module after it has
been included, if you get my drift. It surprises me that this dog
doesn't bark.

The results seem to speak for themselves: include only unwraps the
namespace name from the names that were in the module at the time the
module was included--subsequently adding constants to the previously
included module does not present them unwrapped.
 
7

7stud --

7stud said:
The results seem to speak for themselves: include only unwraps the
namespace name from the names that were in the module at the time the
module was included--subsequently adding constants to the previously
included module does not present them unwrapped.

Nope. That rule doesn't work with example 1. It appears one level of
nesting is required for my rule to hold true.
 
R

Robert Klemme

2009/8/18 Prince Nez said:
=A0 =A0module M1; end
=A0 =A0module M2; include M1; end
=A0 =A0module M1; DOG =3D :woof; end
=A0 =A0module M2; DOG; end
=A0 =A0# =3D> :woof

I can add to a module after it has been included. Neat.

=A0 =A0module M1; DOG =3D :woof; end
=A0 =A0module M2; include M1; end
=A0 =A0module M3; include M2; end
=A0 =A0module M3; DOG; end
=A0 =A0# =3D> :woof

Including a module seems to give me any modules that it includes. Swish.

=A0 =A0module M2; end
=A0 =A0module M3; include M2; end
=A0 =A0module M1; DOG =3D :woof; end
=A0 =A0module M2; include M1; end
=A0 =A0module M3; DOG; end
=A0 =A0# =3D> NameError: uninitialized constant M3::DOG

So I assumed I'd be able to include a module in a module after it has
been included, if you get my drift. It surprises me that this dog
doesn't bark.

Inclusion apparently works by extracting the ancestors of a module at
inclusion time and placing them in the ancestor chain of the class:

irb(main):001:0> module A
irb(main):002:1> def foo; "foo"; end
irb(main):003:1> end
=3D> nil
irb(main):004:0> A.ancestors
=3D> [A]
irb(main):005:0> class C
irb(main):006:1> include A
irb(main):007:1> end
=3D> C
irb(main):008:0> C.ancestors
=3D> [C, A, Object, Kernel, BasicObject]
irb(main):009:0> C.new.foo
=3D> "foo"
irb(main):010:0> module B
irb(main):011:1> def bar; "bar"; end
irb(main):012:1> end
=3D> nil
irb(main):013:0> module A
irb(main):014:1> include B
irb(main):015:1> end
=3D> A
irb(main):016:0> A.ancestors
=3D> [A, B]
irb(main):017:0> C.ancestors
=3D> [C, A, Object, Kernel, BasicObject]
irb(main):018:0> C.new.bar
NoMethodError: undefined method `bar' for #<C:0x100de5c0>
from (irb):18
from /opt/bin/irb19:12:in `<main>'
irb(main):019:0> class C
irb(main):020:1> include A
irb(main):021:1> end
=3D> C
irb(main):022:0> C.ancestors
=3D> [C, A, B, Object, Kernel, BasicObject]
irb(main):023:0> C.new.bar
=3D> "bar"
irb(main):024:0>

As you can see, you can fix that by reincluding the module.

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top