【问题标题】:How do I get class-object from string "A::B::C" in Ruby?如何从 Ruby 中的字符串“A::B::C”获取类对象?
【发布时间】:2010-07-23 00:08:58
【问题描述】:

以下示例失败

class A
  class B
  end
end
p Object.const_get 'A' # => A
p Object.const_get 'A::B' # => NameError: wrong constant name A::B

更新

关于之前提出的主题的问题:

  1. Cast between String and Classname
  2. Ruby String#to_class
  3. Get a class by name in Ruby?

最后一个gives a nice solution可以进化成

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

【问题讨论】:

  • 如果我想声明使用to_class 方法并将其值分配给class 中的CONSTANT 会发生什么情况,例如class A begin MY_CONST = "SomeOtherClass".to_class end ?例如,如果在 initialize 之外调用,我会得到未初始化的常量。 class_eval,我可以尝试什么?谢谢!

标签: ruby class object


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    这是 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 开始,然后使用双分号之间的每个名称作为垫脚石,以达到您想要的常数。

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-04-09
          • 2018-05-16
          • 1970-01-01
          • 1970-01-01
          • 2013-07-01
          • 1970-01-01
          • 2013-02-04
          • 2016-10-24
          相关资源
          最近更新 更多