2011-02-06 14 views
12

Digamos que tengo tres clases, cada una define en su propio archivo. p.ej. ClaseA en ClassA.rb etc ...No se puede incluir una Clase en otra clase en Ruby: constante no inicializada (NameError)

class ClassA 
    def initialize 
    end 

    def printClassA 
    puts "This is class A" 
    end 
end 

class ClassB 
    def initialize 
    end 

    def printClassB 
    puts "This is class B" 
    end 
end 

class ClassC 

    def initialize 
    end 

    def bothClasses 
    a = ClassA.new 
    b = ClassB.new 
    a.printClassA 
    b.printClassB 
    end 
end 

Como se puede ver, ClassC necesita las otras dos clases con el fin de funcionar correctamente. Supongo que debe haber una forma de importar/incluir/cargar las otras dos clases en ClassC.

Soy nuevo en Ruby y he probado todas las permutas de cargar/incluir/requerir y no puedo encontrar la manera de hacerlo funcionar.

que normalmente apenas consigo:

classc.rb:2:in `<class:ClassC>': uninitialized constant ClassC::ClassA (NameError) 
    from classc.rb:1:in `<main>' 

O un error de sintaxis con mi importación/include/require declaraciones.

Usando Windows 7, Ruby 1.9.2, RadRails, todos los archivos están en el mismo proyecto y carpeta de origen.

Lo siento si esta pregunta es similar a algunas de las otras preguntas aquí, pero la mayoría de las respuestas para resolver la "constante no inicializada" es "solo requiere el archivo". Lo intenté y no está funcionando.

Respuesta

19

Creo que su problema es que $:, la variable que controla dónde require busca archivos, ya no incluye el directorio actual en Ruby 1.9.2 y superior (por razones de seguridad). A decir Rubí dónde buscar el archivo, lo que necesita hacer uno de:

require_relative 'ClassA' # which looks in the same directory as the file where the method is called 

# or # 

require './ClassA' # which looks in the current working directory 
+0

Muchas gracias. Wow – user604886

3

Si guardo todo en un solo archivo, y añadir dos líneas a su código funciona bien en 1.9.2:

class ClassA 
    def initialize 
    end 

    def printClassA 
    puts "This is class A" 
    end 
end 

class ClassB 
    def initialize 
    end 

    def printClassB 
    puts "This is class B" 
    end 
end 

class ClassC 

    def initialize 
    end 

    def bothClasses 
    a = ClassA.new 
    b = ClassB.new 
    a.printClassA 
    b.printClassB 
    end 
end 

c = ClassC.new 
c.bothClasses 
# >> This is class A 
# >> This is class B 

Eso me dice que el código está bien, el problema está en la inclusión de los archivos.

que divide a cabo las dos primeras clases en archivos separados, "classa.rb" y "classb.rb", respectivamente, a continuación, el archivo modificado a:

require_relative './classa' 
require_relative './classb' 

class ClassC 

    def initialize 
    end 

    def bothClasses 
    a = ClassA.new 
    b = ClassB.new 
    a.printClassA 
    b.printClassB 
    end 
end 

c = ClassC.new 
c.bothClasses 

Después de ejecutarlo Me dieron los mismos resultados que muestran funcionó correctamente

Uso './path/to/file' porque es autodocumentado donde estoy buscando, pero 'path/to/file', o, en este caso 'classa', también funcionaría.

Luego, cambié a Ruby 1.8.7, y cambié las líneas require_relative a require, y guardé nuevamente el archivo. Ejecutarlo desde la línea de comandos funcionado correctamente de nuevo:

require './classa' 
require './classb' 

class ClassC 

    def initialize 
    end 

    def bothClasses 
    a = ClassA.new 
    b = ClassB.new 
    a.printClassA 
    b.printClassB 
    end 
end 

c = ClassC.new 
c.bothClasses 

Por razones de seguridad, Ruby 1.9+ elimina el directorio actual ''. de la lista de directorios buscados por require. Debido a que sabían que los perseguiríamos con horquillas y sopletes, agregaron el comando require_relative, que permite realizar búsquedas en el directorio actual y debajo.

+0

¿Los pusiste en tres archivos separados? Funcionará bien si están todos en el mismo archivo .rb. – user604886

+0

Intenta leer la respuesta ahora. He terminado de editarlo. –

Cuestiones relacionadas