Given that I have a constant name of Foo::Bar::Baz
, how can I drill down through each of these levels and determine if the constant exists?
Asked
Active
Viewed 98 times
2
Kyle Decot
- 19,418
- 35
- 132
- 245
-
1Is your question whether `Foo::Bar` and `Foo` exist? AFAIK, Ruby won't create `Foo::Bar::Baz` unless `Foo::Bar` already exists. – Neil Slater May 24 '13 at 20:45
4 Answers
3
defined?(Foo) # => nil
module Foo; end
defined?(Foo) # => "constant"
defined?(Foo::Bar) # => nil
module Foo::Bar; end
defined?(Foo::Bar) # => "constant"
defined?(Foo::Bar::Baz) # => nil
module Foo::Bar; Baz = :baz end
defined?(Foo::Bar::Baz) # => "constant"
sawa
- 156,411
- 36
- 254
- 350
1
Here's what I ended up doing in case anyone else runs into this:
unless Object.const_defined? const_name
const_name.split('::').inject(Object) do |obj, const|
unless obj.const_defined? const
# create the missing object here...
end
obj.const_get(const)
end
end
Kyle Decot
- 19,418
- 35
- 132
- 245
-
2
-
I've updated my answer to use this which eliminates the need for ActiveSupport. Thanks! – Kyle Decot May 26 '13 at 02:13
1
It sounds like you want to use the defined? operator. Check if a constant is already defined has more on this.
-
-
To some extent, yes. But it cannot be (thanks Heaven!) redefined. Sometimes I wish that `#!` was not a method, too. Anyway, +1, correct answer. – Boris Stitnicky May 24 '13 at 21:25
1
Other people talk about the defined?
operator (yes, it's a built-in unary operator, not a method!!!), but there are other ways. I personally favor this one:
constants #=> a big array of constant names
constants.include? :Foo #=> false
module Foo; end
constants.include? :Foo #=> true
Foo.constants.include? :Bar #=> false
module Foo
module Bar; end
end
Foo.constants.include? :Bar #=> true
# etc.
One thing I have to admit about defined?
operator is its reliability. It is not a metho and thus can never be redefined, and thus always does what you expect of it. On the other hand, it is possible to use more roundabout (and less reliable) ways, such as:
begin
Foo::Bar::Baz
puts "Foo::Bar::Baz exists!"
rescue NameError
puts "Foo::Bar::Baz does not exist!"
end
Boris Stitnicky
- 11,743
- 4
- 50
- 69