From: Nikolai Weibull Date: 2012-03-22T16:03:34+09:00 Subject: Re: What’s the best way to check if a feature/class has been loaded? On Thu, Mar 22, 2012 at 06:56, Xavier Noria wrote: > On Thu, Mar 22, 2012 at 6:15 AM, Nikolai Weibull wrote: >>  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. > We are supposedly emulating defined? somehow but for constant paths and > without going up the ancestor chain in each step doesn't it? defined? does > not call const_missing. True, I was seeing the wrong test output for that one. >> 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. > File names and class objects, and module objects, and constants... you > cannot derive one from the other. They are decoupled in Ruby except for the > fact that the class/module keywords assign, and that if you assign an > anonymus class/module to a constant, then its name is set after the > constant. > > But in Ruby file foo.rb can define the constant Bar, which may hold a module > whose name is "Wadus". They are quite orthogonal features. Yes, I realize that, but let’s forget the constant bit (as I tried to do in the part that you cut out from the rest of this discussion on $LOADED_FEATURES, require, and provided?) and focus on the original problem of determining if a feature is available or not. In my first e-mail I explained that I’d been using defined? to perform such tests, but that it doesn’t work as intended. I proposed an alternative to defined? that tried to walk a constant path without ever returning to the top level, but I wasn’t happy with the solution and, as we’ve seen, there are semantic issues with such a solution (should const_missing be called or not?). I was, however, originally looking for a better alternative to the constant lookup altogether. That’s why I mentioned “feature” in my first e-mail. As I said, Ruby uses the (expanded) path of the argument to require as the “feature”. If Ruby provided a convenient way to check if a path was in $LOADED_FEATURES that’d solve my use case. This can of course be emulated, and I’m surely making too big a deal about this, but I’d rather have Kernel.provided? that wraps the extant rb_provided than having to define def provided?(path) $LOADED_FEATURES.any?{ |e| e.end_with? path + File.extname(e) } end for each project that needs this functionality. Finally, such a definition can never truly emulate rb_provided (or what the return value would be from require), as Ruby doesn’t expose the “loading” table. (This solution won’t take autoloads into account either, if one wants that to be done, but they’re going away in 3.0, so let’s ignore them ;-)