Hi!
What’s the best way to check if a feature/class has been loaded?
I’ve been using
defined? A::C
but that fails to give me the correct result if A is a class and B::C
is defined, but A::C isn’t defined, as Ruby will then first resolve
Here’s a test case:
class A
end
module B
end
p defined? A::C # => nil
module B
module C
end
end
p defined? A::C # => "constant"
The only solution I can think of is to do
def feature?(path)
path.split('::').reduce(Object){ |o, e| begin o.const_get(e, false);
rescue NameError; return nil; end }
end
but that won’t work in 1.8.7, as there’s no second argument to
Module#const_get in 1.8.7. A solution that works across the 1.8/1.9
divide might be
def feature?(path)
const = path.split('::').reduce(Object){ |o, e| begin o.const_get(e);
rescue NameError; return nil; end }
const.name == path ? const : nil
end
and even though that works, I’d rather have something simpler,
something built-in.
An alternative would be to check $LOADED_FEATURES, but, again, the
internals of how require works have changed between 1.8 and 1.9 and,
considering things like file-name extensions and one mustn’t forget
about autoload and its semantics, would also be best left to built-in
functionality.
So, how does one check for the presence of A::C without
accidentally referencing top-level constants?
···
A::B to the top-level constant B and then resolve C within B.