Ruby 'requiere' error: no se puede cargar dicho archivo

169

Tengo un archivo, main.rb con el siguiente contenido:

require "tokenizer.rb"

El archivo tokenizer.rb está en el mismo directorio y su contenido es:

class Tokenizer
    def self.tokenize(string)
        return string.split(" ")
    end
end

Si intento ejecutar main.rb me sale el siguiente error:

C:\Documents and Settings\my\src\folder>ruby main.rb

C:/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- tokenizer.rb (LoadError)
        from C:/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require '
        from main.rb:1:in `<main>'

Acabo de notar que si uso en loadlugar de requiretodo funciona bien. ¿Cuál puede ser el problema aquí?

El monje codificador
fuente
Pregunta relacionada: stackoverflow.com/questions/2900370/…
Andrew Grimm
Compruebe que el archivo tiene .rbextensión
onmyway133

Respuestas:

189

Acabo de intentarlo y funciona require "./tokenizer". Espero que esto ayude.

Pascal
fuente
15
Esto supone que el CWD es el directorio en el que se almacenan los scripts.
David Grayson
25
... por eso creo que es mejor usar require_relativecomo lo hice en mi respuesta.
David Grayson
180

Solo haz esto:

require_relative 'tokenizer'

Si coloca esto en un archivo Ruby que está en el mismo directorio tokenizer.rb, funcionará bien sin importar cuál sea su directorio de trabajo actual (CWD).

Explicación de por qué esta es la mejor manera.

Las otras respuestas afirman que debe usar require './tokenizer', pero esa es la respuesta incorrecta , porque solo funcionará si ejecuta su proceso Ruby en el mismo directorio que se tokenizer.rbencuentra. Casi la única razón para considerar el uso de requireesa manera sería si necesita admite Ruby 1.8, que no tiene require_relative.

La require './tokenizer'respuesta podría funcionar para usted hoy, pero limita innecesariamente las formas en que puede ejecutar su código Ruby. Mañana, si desea mover sus archivos a un directorio diferente, o simplemente desea iniciar su proceso Ruby desde un directorio diferente, tendrá que repensar todas esas requiredeclaraciones.

Usar requirepara acceder a los archivos que están en la ruta de carga es algo bueno y las gemas de Ruby lo hacen todo el tiempo. Pero no debe comenzar el argumento requirecon un a .menos que esté haciendo algo muy especial y sepa lo que está haciendo.

Cuando escribe código que hace suposiciones sobre su entorno, debe pensar cuidadosamente sobre qué suposiciones hacer. En este caso, hay hasta tres formas diferentes de requerir el tokenizerarchivo, y cada una asume de manera diferente:

  1. require_relative 'path/to/tokenizer': Asume que la ruta relativa entre los dos archivos fuente de Ruby se mantendrá igual.
  2. require 'path/to/tokenizer': Asume que path/to/tokenizerestá dentro de uno de los directorios en la ruta de carga ( $LOAD_PATH). Esto generalmente requiere una configuración adicional, ya que debe agregar algo a la ruta de carga.
  3. require './path/to/tokenizer': Asume que la ruta relativa desde el directorio de trabajo actual del proceso Ruby hasta tokenizer.rbse mantendrá igual.

Creo que para la mayoría de las personas y la mayoría de las situaciones, las suposiciones hechas en las opciones n. ° 1 y n. ° 2 tienen más probabilidades de ser ciertas con el tiempo.

David Grayson
fuente
¿Puedes decir cuál es el significado de esto? ¿Qué hace detrás de escena? Gracias.
sid smith
No hay mucho que saber. Aquí está la documentación y el código fuente de require_relative.
David Grayson
90

Ruby 1.9 ha eliminado el directorio actual de la ruta de carga, por lo que deberá hacer un requisito relativo en este archivo, como dice David Grayson:

require_relative 'tokenizer'

No hay necesidad de sufijo .rb, ya que Ruby es lo suficientemente inteligente como para saber que a eso te refieres de todos modos.

Ryan Bigg
fuente
1
Sabía que esto iba a ser algo estúpido, gracias por la ayuda
The Coding Monk
3
Esto supone que el CWD es el directorio en el que se almacenan los scripts.
David Grayson
@RyanBigg: soy nuevo en Ruby. ¿Puede explicar qué significa esto Ruby 1.9 has removed the current directory from the load path? ¿Cuál es este directorio actual y ruta de carga? Gracias.
sid smith
¿Qué se supone que debo leer en el OP? El hecho de que el OP tenga el CWD igual al directorio con los scripts no significa que siempre vaya a ser así, por lo que me gusta impulsar una solución más robusta como usar require_relative. Mañana podría escribir cd ..y luego ruby folder/main.rby estar triste porque su solución ya no funciona. No creo que usar requiretenga ningún beneficio aquí.
David Grayson
1
Actualizado para require_relative(que no existía, o no lo sabía al momento de la publicación)
Ryan Bigg
37

requirecarga un archivo desde el $LOAD_PATH. Si desea solicitar un archivo relativo al archivo que se está ejecutando actualmente en lugar del archivo $LOAD_PATH, use require_relative.

Jörg W Mittag
fuente
14

Yo recomendaria,

load './tokenizer.rb'

Dado que sabe que el archivo está en el mismo directorio de trabajo.

Si intenta solicitarlo en relación con el archivo, puede usar

require_relative 'tokenizer'

Espero que esto ayude.

Matthew Brock Carey
fuente
11

Otro pequeño método es incluir el directorio actual en su ruta de carga con

$:.unshift('.')

Puede empujarlo a la matriz $: ($ LOAD_PATH) pero unshift lo obligará a cargar su directorio de trabajo actual antes del resto de la ruta de carga.

Una vez que haya agregado su directorio actual en su ruta de carga, no necesita seguir especificando

 require './tokenizer' 

y puedo volver a usar

require 'tokenizer'
Pseudomonkey
fuente
5

Esto funcionará bien si está en un directorio de la biblioteca de gemas y este es el tokenizer.rb

require_relative 'tokenizer/main'
Douglas G. Allen
fuente
1

Usé jruby-1.7.4 para compilar mi código ruby.

require 'roman-numerals.rb' 

es el código que arrojó el siguiente error.

LoadError: no such file to load -- roman-numerals
  require at org/jruby/RubyKernel.java:1054
  require at /Users/amanoharan/.rvm/rubies/jruby-1.7.4/lib/ruby/shared/rubygems/custom_require.rb:36
   (root) at /Users/amanoharan/Documents/Aptana Studio 3 Workspace/RubyApplication/RubyApplication1/Ruby2.rb:2

Quité rb de require y di

require 'roman-numerals' 

Funcionó bien.

Ananth Srinivasan
fuente
1

Para aquellos que están absolutamente seguros de que su ruta relativa es correcta, ¡mi problema fue que mis archivos no tenían la .rbextensión! (A pesar de que he utilizado RubyMinepara crear los archivos y seleccionado que eran Rubyarchivos en la creación.)

¡Verifique dos veces las extensiones de archivo en su archivo!

Andy Barnett
fuente
1

¿Qué hay de incluir el directorio actual en la ruta de búsqueda?

ruby -I. main.rb
Hans-J. Schmid
fuente
0

El problema es que requireno se carga desde el directorio actual. Esto es lo que pensé también, pero luego encontré este hilo . Por ejemplo probé el siguiente código:

irb> f = File.new('blabla.rb')
=> #<File:blabla.rb>
irb> f.read
=> "class Tokenizer\n    def self.tokenize(string)\n        return string.split(
\" \")\n    end\nend\n"
irb> require f
LoadError: cannot load such file -- blabla.rb
        from D:/dev/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `req
uire'
        from D:/dev/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `req
uire'
        from (irb):24
        from D:/dev/Ruby193/bin/irb:12:in `<main>'

Como se puede ver, leyó bien el archivo, pero no pude requerirlo (no se reconoció la ruta). y aquí va el código que funciona:

irb f = File.new('D://blabla.rb')
=> #<File:D://blabla.rb>
irb f.read
=> "class Tokenizer\n    def self.tokenize(string)\n        return string.split(
\" \")\n    end\nend\n"
irb> require f
=> true

Como puede ver si especifica la ruta completa, el archivo se carga correctamente.

Boris Strandjev
fuente
1
Es una cuestión de elección. Personalmente, siempre me gusta probar lo que estoy haciendo en la consola interactiva. Cometo bastantes errores y me gusta recibir comentarios interactivos.
Boris Strandjev
0

Primero :

$ sudo gem install colored2

Y, debe ingresar su contraseña

Luego :

$ sudo gem update --system  

Aparece Actualizando rubygems-update ERROR: Al ejecutar gem ... (OpenSSL :: SSL :: SSLError) el nombre de host "gems.ruby-china.org" no coincide con el certificado del servidor

Luego:

$  rvm -v
$ rvm get head

Último ¿Qué idioma quieres usar? [Swift / ObjC]

ObjC

¿Le gustaría incluir una aplicación de demostración con su biblioteca? [ Sí No ]

si

¿Qué marcos de prueba usarás? [Specta / Kiwi / Ninguno]

Ninguna

¿Te gustaría hacer pruebas basadas en la vista? [ Sí No ]

No

¿Cuál es tu prefijo de clase?

XMG

Ejecutando pod install en su nueva biblioteca.

Lxt_91424
fuente
-2

Necesitas dar el camino. Al menos debe dar la ruta desde el directorio actual. Funcionará seguro. ./nombre del archivo

Dittu Joju
fuente
Para mayor claridad, creo que debería dar parte repetida del código aquí con la solución. El voto
negativo