From: Peter McLain Date: 2010-03-05T04:31:39+09:00 Subject: [ruby-core:28482] Question on scoped constant resolution Class vs Module 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