On Wed, Mar 21, 2012 at 22:11, Xavier N. [email protected] wrote:
On Wed, Mar 21, 2012 at 9:51 PM, Nikolai W. [email protected] wrote:
There’s 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, we’ve already come to that conclusion. You don’t need to 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’re responding
to’s name like that. It’s like your speaking to me as if I was 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.