2010-07-23 6 views
9

El siguiente ejemplo no¿Cómo obtengo class-object de la cadena "A :: B :: C" en Ruby?

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

ACTUALIZACIÓN

Preguntas sobre el tema preguntado antes:

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

El último gives a nice solution que puede ser convertido en

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 
+0

¿Qué pasa si me gustaría declarar el uso del método 'to_class' y asignar su valor a un' 'CONSTANT' dentro de un class', por ejemplo, 'clase A begin MY_CONST =" SomeOtherClass ".to_class end'? Me sale constante sin inicializar si estoy llamando a 'initialize', por ejemplo. 'class_eval', ¿qué podría intentar? ¡Gracias! – Dr1Ku

Respuesta

7

Vas a tener que manualmente "parse" los dos puntos usted mismo y llamar const_get en el módulo padre/clase:

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 

Alguien ha escrito un qualified_const_get que puede ser de su interés.

6

Aquí es constantize método de Rails:

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 

Sede, que comienza en el Object encima de todo, entonces utiliza cada nombre en medio de los dobles puntos y comas como un trampolín para llegar a la constante que querer.

Cuestiones relacionadas