【发布时间】:2013-05-24 20:29:34
【问题描述】:
鉴于我有一个常量名称 Foo::Bar::Baz,我如何深入了解每个级别并确定该常量是否存在?
【问题讨论】:
-
你的问题是
Foo::Bar和Foo是否存在? AFAIK,除非Foo::Bar已经存在,否则 Ruby 不会创建Foo::Bar::Baz。
标签: ruby-on-rails ruby
鉴于我有一个常量名称 Foo::Bar::Baz,我如何深入了解每个级别并确定该常量是否存在?
【问题讨论】:
Foo::Bar和Foo是否存在? AFAIK,除非 Foo::Bar 已经存在,否则 Ruby 不会创建 Foo::Bar::Baz。
标签: ruby-on-rails ruby
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"
【讨论】:
其他人谈论defined? 运算符(是的,它是内置的一元运算符,而不是方法!!!),但还有其他方法。我个人比较喜欢这个:
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.
关于defined? 运算符,我必须承认的一件事是它的可靠性。它不是一种方法,因此永远无法重新定义,因此总是按照您的期望行事。另一方面,可以使用更多迂回(且不太可靠)的方式,例如:
begin
Foo::Bar::Baz
puts "Foo::Bar::Baz exists!"
rescue NameError
puts "Foo::Bar::Baz does not exist!"
end
【讨论】:
如果其他人遇到这种情况,我最终会这样做:
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
【讨论】:
#const_defined? ?
听起来你想使用定义的?操作员。 Check if a constant is already defined 对此有更多了解。
【讨论】:
#! 也不是一种方法。无论如何,+1,正确答案。