File.open, open y IO.foreach en Ruby, ¿cuál es la diferencia?
ruby raise (1)
Hay diferencias importantes entre esas 3 opciones.
File.open("file").each_line { |line| puts line }
-
File.open
abre un archivo local y devuelve un objeto de archivo - el archivo permanece abierto hasta que llame a
IO#close
de él
open("file").each_line { |line| puts line }
Kernel.open
mira la cadena para decidir qué hacer con ella.
open(".irbrc").class # => File
open("http://google.com/").class # => StringIO
File.open("http://google.com/") # => Errno::ENOENT: No such file or directory - http://google.com/
En el segundo caso, el objeto StringIO
devuelto por Kernel#open
realmente contiene el contenido de http://google.com/ . Si Kernel#open
devuelve un objeto File
, permanece abierto hasta que se IO#close
el IO#close
.
IO.foreach("file") { |line| puts line }
-
IO.foreach
abre un archivo, llama al bloque dado para cada línea que lee y luego cierra el archivo. - No tiene que preocuparse por cerrar el archivo.
File.read("file").each { |line| puts line }
No mencionó esta opción, pero esta es la que usaría en la mayoría de los casos.
-
File.read
lee un archivo completamente y lo devuelve como una cadena. - No tiene que preocuparse por cerrar el archivo.
- En comparación con
IO.foreach
esto deja en claro que se trata de un archivo. - La complejidad de la memoria para esto es O (n). Si sabe que está tratando con un archivo pequeño, esto no es un inconveniente. Pero si puede ser un archivo grande y usted sabe que la complejidad de su memoria puede ser menor que O (n), no use esta opción.
Falla en esta situación:
s= File.read("/dev/zero") # => never terminates
s.each …
Rhode Island
ri es una herramienta que te muestra la documentación de ruby. Lo usas así en tu caparazón.
ri File.open
ri open
ri IO.foreach
ri File#each_line
Con esto puedes encontrar casi todo lo que escribí aquí y mucho más.
Todas las siguientes API hacen lo mismo: abrir un archivo y llamar a un bloque para cada línea. ¿Hay alguna preferencia que debemos usar uno que otro?
File.open("file").each_line {|line| puts line}
open("file").each_line {|line| puts line}
IO.foreach("file") {|line | puts line}