如何从Ruby中的字符串“A :: B :: C”获取类对象?
以下示例失败
class A class B end end p Object.const_get 'A' # => A p Object.const_get 'A::B' # => NameError: wrong constant name A::B
UPDATE
前面提到的关于这个主题的问题
- 在String和Classname之间转换
- Ruby String#to_class
- 在Ruby中按名称获取课程?
最后一个提供了一个很好的解决方案 ,可以演变成
class String def to_class self.split('::').inject(Object) do |mod, class_name| mod.const_get(class_name) end end end class A class B end end p "A::B".to_class # => A::B
您必须自己手动“解析”冒号并在父模块/类上调用const_get
:
ruby-1.9.1-p378 > class A ruby-1.9.1-p378 ?> class B ruby-1.9.1-p378 ?> end ruby-1.9.1-p378 ?> end => nil ruby-1.9.1-p378 > A.const_get 'B' => A::B
有人编写了一个可能感兴趣的qualified_const_get
。
这是Rails的constantize
方法:
def constantize(camel_cased_word) names = camel_cased_word.split('::') names.shift if names.empty? || names.first.empty? constant = Object names.each do |name| constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name) end constant end
看,它从最重要的Object
开始,然后使用双分号之间的每个名称作为踏脚石来获得你想要的常量。
Extlib提供了一个full_const_get
方法,它就是这样做的。
http://github.com/datamapper/extlib/blob/master/lib/extlib/object.rb#L67
您可以包含extlib,也可以复制此实现并自行使用(假设许可与您使用它的任何内容兼容)
您可以使用eval执行此操作,这也适用于const_get不会的某些情况。 这里有一篇很好的文章: http : //blog.sidu.in/2008/02/loading-classes-from-strings-in-ruby.html#.T8j88HlYtXc