sawa
sawa

Reputation: 168269

Nesting versus namespace operator

I had believed that

module A
  module B
    ...
  end
end

and (provided that module A is defined in advance):

module A::B
  ...
end

are equivalent, but it turned out not. Given:

module A
  C = :foo
end

the two forms behave differently:

module A
  module B
    puts C
  end
end
# => :foo

module A::B
  puts C
end
# => NameError: uninitialized constant A::B::C

What is the logic behind this difference? Particularly, why cannot A::B access A::C in the second form (although it can in the first form)?


Update

I found some related posts on the Ruby core:

Upvotes: 2

Views: 122

Answers (1)

Arup Rakshit
Arup Rakshit

Reputation: 118299

Module::nesting is a good tool to answer you here. As the doc is saying - Returns the list of Modules nested at the point of call.

Here is the reason why the below one is not working :

module A
  C = :foo
end

module A::B
  puts C
end

To let this explain I would write something like below :

module A
  C = :foo
end

module A::B
  $a = Module.nesting
end
$a # => [A::B]

So from the output of $a,it is clear that why the constant C is not accessible.

The reason why the below code does work :

module A
  C = :foo
end
module A
  module B
    puts C
  end
end

To let this explain I would write something like below :

module A
  C = :foo
end

module A
  module B
    $a = Module.nesting
  end
end
$a # => [A::B, A]

So from the output of $a,it is clear that why the constant C is accessible.

Read here(Everything you ever wanted to know about constant lookup in Ruby) is an wonderful resource for the same I just found.

Upvotes: 1

Related Questions