On Wed, Mar 21, 2012 at 22:11, Xavier Noria <fxn / hashref.com> wrote: > On Wed, Mar 21, 2012 at 9:51 PM, Nikolai Weibull <now / bitwi.se> wrote: > >> There a timing issue with using const_defined? followed by const_get >> instead of calling const_get directly and catching NameError. > > > What do you mean? I mean that if const_defined? returns true, then between that code being executed and the call to const_get, some other piece of code may remove the constant, resulting in an uncaught NameError. > The problem with const_get is that it follows the ancestors, of course, and > you have no way around that in 1.8. Yes, wee already come to that conclusion. You don needo keep repeating it. I see that you completely cut out the part about const_defined? not calling const_missing, which is a rather big part of the problem with using const_defined? in the first place. >> 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 > Nikolai, I don't really understand what you need. Xavier, please don¡Çt begin sentences with the person you¡Çreesponding to¡Çs name like that. It¡Çs like your speaking to me as if Ias a child and it feels very condescending. > You are askind for > defined? X::Y that goes step by step and your original code does raise an > error for X::Y integer. I don¡Çt follow. > Then this second version cannot say that X::Y is defined in > > module X > Y = nil > end True. > And you refuse to reuse much more simple and proven existing solutions. You¡Çre making it sound like I¡Çm being stubborn. I just don¡Çt think your proposed solution is better. > You want something with so special semantics that definitely is NOT > built-in. That answers you original question. Thank you for building me a straw man. I¡Çve always wanted one. I want a way to tell if a class or module has been defined/loaded. The check would then be to see if X was loaded in your example above, not X::Y. An alternative is to check $LOADED_FEATURES. This isn¡Çt straightforward either, as it doesn¡Çt contain the exact argument given to require. There are internal functions like rb_provided that could have been exposed to make it easy to check if a feature had been loaded/is available. This part of Ruby is surely inspired by Emacs¡Ç way of doing this, see http://www.gnu.org/software/emacs/manual/html_node/elisp/Named-Features.html but doesn¡Çt provide a way to check if a feature has been loaded. (There¡Çs a difference here, of course, as Ruby implicitly uses the (expanded) path, with possible suffixes/extensions, of the argument to require as the feature, not a symbol as Emacs forces you to explicitly use as an argument to provide.) To sum up, ruby should provide a method ¡Èprovided?¡É that checks if its argument would return true or false when given as an argument to require. Provided? would return this results negation. Checking the presence of constants is a workaround that I¡Çve been using in the past, but was recently burned by, as, even in the case of using defined?, this may travel unwanted paths in the resolution of such constants.