代码之家  ›  专栏  ›  技术社区  ›  Andy

如何从Ruby中的字符串“a::b::c”获取类对象?

  •  9
  • Andy  · 技术社区  · 14 年前

    以下示例失败

    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
    
    4 回复  |  直到 12 年前
        1
  •  7
  •   Mark Rushakoff    14 年前

    您必须自己手动“解析”冒号并调用 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
  •  6
  •   Paige Ruten    14 年前

    这里是铁轨 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
  •  0
  •   Glenjamin    14 年前

    extlib提供 full_const_get 方法,只执行此操作。

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

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

        4
  •  0
  •   jacklin    12 年前

    你也可以用eval来做这个,在某些情况下,const-get是不会的。 这里有一篇很好的文章: http://blog.sidu.in/2008/02/loading-classes-from-strings-in-ruby.html#.T8j88HlYtXc