如何从Ruby中的字符串“A :: B :: C”获取类对象?

时间:2022-10-30 00:27:32

The following example fails

以下示例失败

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

UPDATE

Questions about the topic asked earlier:

前面提到的关于这个主题的问题

  1. Cast between String and Classname
  2. 在String和Classname之间转换
  3. Ruby String#to_class
  4. Ruby String#to_class
  5. Get a class by name in Ruby?
  6. 在Ruby中按名称获取课程?

The last one gives a nice solution which can be evolved into

最后一个提供了一个很好的解决方案,可以演变成

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

4 个解决方案

#1


7  

You'll have to manually "parse" the colons yourself and call const_get on the parent module/class:

您必须自己手动“解析”冒号并在父模块/类上调用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 

Someone has written a qualified_const_get that may be of interest.

有人编写了一个可能感兴趣的qualified_const_get。

#2


6  

Here is Rails' constantize method:

这是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

See, it starts at the Object on top of it all, then uses each name in between the double semicolons as a stepping stone to get to the constant you want.

看,它从最重要的对象开始,然后使用双分号之间的每个名称作为踏脚石来获得你想要的常量。

#3


0  

Extlib provides a full_const_get method, which does just this.

Extlib提供了一个full_const_get方法,它就是这样做的。

http://github.com/datamapper/extlib/blob/master/lib/extlib/object.rb#L67

http://github.com/datamapper/extlib/blob/master/lib/extlib/object.rb#L67

You could either include extlib, or copy this implementation and use it yourself (assuming the licensing is compatible with whatever you're using it for)

您可以包含extlib,也可以复制此实现并自行使用(假设许可与您使用它的任何内容兼容)

#4


0  

You can do this with eval also which works in some cases where const_get won't. There's a good article on this here: http://blog.sidu.in/2008/02/loading-classes-from-strings-in-ruby.html#.T8j88HlYtXc

您可以使用eval执行此操作,这也适用于const_get不会的某些情况。这里有一篇很好的文章:http://blog.sidu.in/2008/02/loading-classes-from-strings-in-ruby.html#.T8j88HlYtXc

#1


7  

You'll have to manually "parse" the colons yourself and call const_get on the parent module/class:

您必须自己手动“解析”冒号并在父模块/类上调用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 

Someone has written a qualified_const_get that may be of interest.

有人编写了一个可能感兴趣的qualified_const_get。

#2


6  

Here is Rails' constantize method:

这是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

See, it starts at the Object on top of it all, then uses each name in between the double semicolons as a stepping stone to get to the constant you want.

看,它从最重要的对象开始,然后使用双分号之间的每个名称作为踏脚石来获得你想要的常量。

#3


0  

Extlib provides a full_const_get method, which does just this.

Extlib提供了一个full_const_get方法,它就是这样做的。

http://github.com/datamapper/extlib/blob/master/lib/extlib/object.rb#L67

http://github.com/datamapper/extlib/blob/master/lib/extlib/object.rb#L67

You could either include extlib, or copy this implementation and use it yourself (assuming the licensing is compatible with whatever you're using it for)

您可以包含extlib,也可以复制此实现并自行使用(假设许可与您使用它的任何内容兼容)

#4


0  

You can do this with eval also which works in some cases where const_get won't. There's a good article on this here: http://blog.sidu.in/2008/02/loading-classes-from-strings-in-ruby.html#.T8j88HlYtXc

您可以使用eval执行此操作,这也适用于const_get不会的某些情况。这里有一篇很好的文章:http://blog.sidu.in/2008/02/loading-classes-from-strings-in-ruby.html#.T8j88HlYtXc