Ruby Namespaces / Modules

If I'm in the middle of module A::b::C, and I want to reference a class
from A::B or from A::b::D, do I need to do ::a::b::Classname (or
::a::b::D::Classname)?

It seems a bit repititous to me. A module shouldn't need to know it's
ancestors all the way up - just what it needs to use. Having to keep
track couples modules to a tree and obstructs refactoring.

So, what say the veteran Rubyists?

Quoting eastcoastcoder@gmail.com:

If I'm in the middle of module A::b::C, and I want to reference a
class from A::B or from A::b::D, do I need to
do ::a::b::Classname (or ::a::b::D::Classname)?

It seems a bit repititous to me. A module shouldn't need to know
it's ancestors all the way up - just what it needs to use.
Having to keep track couples modules to a tree and obstructs
refactoring.

So, what say the veteran Rubyists?

Try it!

module A
   module B
     class Foo
     end
     module D
       class Bar
       end
     end
   end
   module C
     p B::Foo
     p B::D::Bar
   end
end

-mental

mental@rydia.net writes:

Quoting eastcoastcoder@gmail.com:

If I'm in the middle of module A::b::C, and I want to reference a
class from A::B or from A::b::D, do I need to
do ::a::b::Classname (or ::a::b::D::Classname)?

It seems a bit repititous to me. A module shouldn't need to know
it's ancestors all the way up - just what it needs to use.
Having to keep track couples modules to a tree and obstructs
refactoring.

So, what say the veteran Rubyists?

Try it!

module A
   module B
     class Foo
     end
     module D
       class Bar
       end
     end
   end
   module C
     p B::Foo
     p B::D::Bar
   end
end

It's also worth pointing out that:

  class A::b::Foo
    p C
  end

is different to:

  module A
    module B
      class Foo
        p C
      end
    end
  end

The latter may reference A::b::C or A::C, whereas the former cannot.

The latter may reference A::b::C or A::C, whereas the former cannot.

Intersting... why is that?

eastcoastcoder@gmail.com writes:

The latter may reference A::b::C or A::C, whereas the former cannot.

Intersting... why is that?

Doing "module X::Y::Z" (or "class X::Y::Z") will bring only X::Y::Z::*
constants into scope. Constants from outer modules (X::Y::*, X::*)
aren't brought in. Thus, to get all the nested namespaces in scope,
you need to open each one explicitly.

It's been debated:

http://rubyurl.com/1NH
http://rubyurl.com/0KZ