On Wed, Mar 21, 2012 at 20:48, Xavier Noria <fxn / hashref.com> wrote: > On Wed, Mar 21, 2012 at 8:17 PM, Nikolai Weibull <now / bitwi.se> wrote: > Take into account that #feature? assumes the argument matches the constant > name, which may not be the case. For example > > module A > module B > end > end > > module C > D = A::B > end > > In that code A::B and C::D are defined constants that store the same module > object, but #feature? returns false on C::D. True, but #feature? wasn¡Çt written to take such things into account. > It would be more correct to rely on const_defined? like Active Support does. There¡Çs a timing issue with using const_defined? followed by const_get instead of calling const_get directly and catching NameError. Also, using const_defined? won¡Çt invoke const_missing, which might set the constant for you, if that¡Çs what you want to have happen. I guess def feature?(path) path.split('::').reduce(Object){ |o, e| c = begin o.const_get(e); rescue NameError; return nil end return nil if c == (o != Object and begin Object.const_get(e); rescue NameError; nil end) c } end might work, as it tries to make sure that we don¡Çt return to the top level at any point in the path resolution, but is a lot more complicated than I think that it should have to be.