Module#constants

X

Xavier Noria

According to my trials nor Module#constants neither Module#const_get
work with constants defined in enclosing modules:

module M
C = 1
module N
C # -> 1
end
end

M::N.constants # -> []
M::N.const_get("C") # -> NameError

Looks as if they only took into account ancestors.

But the Pickaxe says that Module#constants:

"Returns an array of the names of the constants accessible in mod.
This includes the names of constants in any included modules (example
at start of section)."

Does "This includes" mean "These are"? Is there a way to obtain "M::C"
as qualified name of a constant visible by N?

-- fxn
 
X

Xavier Noria

According to my trials nor Module#constants neither Module#const_get
work with constants defined in enclosing modules:

module M
C = 1
module N
C # -> 1
end
end

M::N.constants # -> []
M::N.const_get("C") # -> NameError

Looks as if they only took into account ancestors.

I gues that C is somehow in scope, but there are other examples that
puzzle me:

module M
C = 1
end

module PutSomethingInBetweenJustInCase
end

module M
module N
puts C # -> 1
end
end

Why is M::C in scope there?

-- fxn
 
X

Xavier Noria

for the same reason that File and Object are. imagine if C were
not, then we would have to write

::File.open path

whenever opening a File.

the scope crawls up the nesting.

Thank you! I had once that hypothesis but this example broke it:

module M
C = 1
module N
end
end

M::N.module_eval do
File # -> OK
C # -> NameError
end

File is seen but C is not. So I think there's something more into it.
The best conjecture I have by now is that you need to have the
enclosing module syntactically there with the nested "module/class"s.

However, I have seen that even if there something syntactic the name
of the constant is not used, I mean this works:

module M
C = 1
module N
end
end

X = M
module X
module N
C
end
end

That makes some sense because if X is already a module that module is
reponed, fine, but all the examples together give kind of a mix of
runtime and syntatic things to take into account.

I don't yet understand the complete rule.

-- fxn
 
X

Xavier Noria

However, I have seen that even if there something syntactic the name
of the constant is not used, I mean this works:

module M
C = 1
module N
end
end

X = M
module X
module N
C
end
end

Nah, that didn't add information. When the code is interpreted and we
arrive to "module X" the X constant is looked up and has a module as
value, which happens to be the same module object that is stored under
M. So that example is no different from plain

module M
module N
C
end
end

This test brings some light in what I think I don't understand:

module M
C = 1
module N
end
end

class Module
def const_missing(c)
puts self
end
end

M::N.module_eval do
C
puts self
end

Gives:

Object
M::N

So I think I am narrowing this to how scope works. I know module_eval
sees stuff from the surrounding scope, but I think I have a
misunderstanding between "scope" and "evaluating the block in the
context of M::N".

There's some module that's taken as a starting point to crawl up in
the namespace for constant resolution (Object), and there's a
different module to which method definitions _but not constant
definitions_ apply (the remark about constants is not proven in the
example).

Can anyone define those "two" modules better?

-- fxn
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top