I asked this on ruby-talk, but didn't get anywhere. Someone suggested
I post over here.
Resolution of fully scoped constants behaves differently if there is a
class versus a module in the name:
XYZ = 10
module M
end
class C
end
p defined? M::XYZ # => nil
p defined? C::XYZ # => "constant"
A few questions:
1: Is this difference intended?
2: If so, what is the rationale?
3: Should defined?(C::XYZ) behave differently than C.const_defined?
(:XYZ) ?
4: Is the draft ruby spec correct, or MRI behavior correct, or did I
miss something in the following:
I think the behavior with M::XYZ does not conform to section 11.4.3.2
of the draft ruby spec:
11.4.3.2
(a) the primary-expression is M,
(b) M is a module, do not raise TypeError
(c 1) XYZ is the constant-identifier
(c 2) XYZ is not one of the constants defined in M
(c 3 i) There are no included modules in M (skip)
(c 3 ii) N/A
(c 3 iii) Goto step e of section 11.4.3.1
11.4.3.1
(e) M is not a class
(e 1) Search Object for a binding for XYZ
So, according to the spec, it looks like M:XYZ should resolve to the
XYZ in Object and MRI is incorrect to return nil.
Did I miss something?
The real world occurrence of this was:
return unless defined? RDoc::VERSION # RDoc 1 does not have VERSION
# code that blows up if RDoc 1 being used...
Which does not currently work in MagLev, since MagLev returns
"constant" for defined?RDoc::VERSION. One could argue that the proper
test, which works for both classes and modules in all ruby
implementations, is:
return unless RDoc.const_defined? :VERSION
--
Peter McLain
peter.mclain / gemstone.com