Including a module in an included module.

Discussion in 'Ruby' started by Prince Nez, Aug 18, 2009.

  1. Prince Nez

    Prince Nez Guest

    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.
    --
    Posted via http://www.ruby-forum.com/.
     
    Prince Nez, Aug 18, 2009
    #1
    1. Advertising

  2. Prince Nez

    7stud -- Guest

    Prince Nez wrote:
    > 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.


    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, Aug 18, 2009
    #2
    1. Advertising

  3. Prince Nez

    7stud -- Guest

    7stud -- wrote:
    >
    > 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.

    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, Aug 18, 2009
    #3
  4. 2009/8/18 Prince Nez <>:
    > =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/
     
    Robert Klemme, Aug 18, 2009
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Old Wolf
    Replies:
    7
    Views:
    458
    Kai-Uwe Bux
    Nov 20, 2006
  2. Leaf
    Replies:
    1
    Views:
    277
    Martin v. Löwis
    Nov 22, 2008
  3. Charles Comstock

    ri Module#included entry is incorrect

    Charles Comstock, May 22, 2004, in forum: Ruby
    Replies:
    0
    Views:
    96
    Charles Comstock
    May 22, 2004
  4. Tim Hunter
    Replies:
    1
    Views:
    101
    Dave Thomas
    Nov 1, 2004
  5. Zev Blut
    Replies:
    3
    Views:
    173
    trans. (T. Onoma)
    Nov 24, 2004
Loading...

Share This Page