Ruby не может открыть файл ( Errno::ENOENT ), но тот же путь можно открыть из IRB

У меня есть простой скрипт Ruby, который создает список файлов из массива строк, поэтому у меня есть метод, похожий на этот:

  def initialize( rootpath, name )
    @content = ""
     intermission = ""
     if ( ! (rootpath[-1] == "/" || name[0] == "/" ))
       intermission="/"
       end

     @path= "#{rootpath}#{intermission}#{name}"
     print "Open JavascriptFile from #{@path}" 
     if (! File.exists? @path)
       print "File does not exist!" 
       end
     File.open( @path ).each do |line|
       @content << line
       end
     end

Это называется по строкам:

 files= ['alice.js', 'bob.js', 'claire.js', 'dave.js']
 basepath= "/home/glenatron/projects/myJSProject/"
 files.each do |filename|
    myLoader.new( basepath, filename )
    end

Когда я загружаю свои классы из IRB и запускаю это, я получаю:

Open JavascriptFile from /home/glenatron/projects/myJSProject/alice.js
File does not exist!
Errno::ENOENT: No such file or directory - /home/glenatron/projects/myJSProject/alice.js

Насколько я понимаю, это означает, что файла не существует.

Однако файл не только определенно существует, в IRB я могу вставить точно такой же путь и увидеть его содержимое — простое File.open("/home/glenatron/projects/myJSProject/alice.js").each { | line | print line } показывает полное содержимое файла. Так почему же я могу сделать это из прямого запроса командной строки, а не из моего класса Ruby? Пытается ли он прочитать локальный путь вместо полного пути, который я передаю?


person glenatron    schedule 08.11.2013    source источник
comment
Попробуйте упростить свой код и опубликовать его целиком.   -  person David Grayson    schedule 08.11.2013


Ответы (2)


Защитите File.open .. строки блоком else:

 if (! File.exists? @path)
   print "File does not exist!" 
 else # <---
   File.open( @path ).each do |line|
     @content << line
   end
 end  # <----

или вернуться ранее в блоке if:

 if (! File.exists? @path)
   print "File does not exist!" 
   return
 endif

В противном случае код всегда будет пытаться открыть файл, даже если он не существует.


Используйте File::join для соединения компонентов пути:

File.join("/home/glenatron/projects/myJSProject/", "alice.js")
# => "/home/glenatron/projects/myJSProject/alice.js"
File.join("/home/glenatron/projects/myJSProject", "alice.js")
# => "/home/glenatron/projects/myJSProject/alice.js"

Отредактируйте, чтобы привести решение (в комментариях) к ответу: чтобы найти точный путь, используйте p @path - это показало, что путь, который пытался открыть, выглядел так, когда он не удался: /home/glenatron/projects/myJSProject/alice.js\r, который вызывал проблему. Простой @path.strip! разрешил это, как только это стало ясно.

person falsetru    schedule 08.11.2013
comment
Спасибо - я сделаю это, когда код будет готов для серьезного использования, но сейчас мне нужно знать почему, когда файл определенно существует и я могу открыть его из Irb Руби думает, что нет? - person glenatron; 08.11.2013
comment
@glenatron, вы запускаете IRB и скрипт ruby ​​на одной машине? - person falsetru; 08.11.2013
comment
Мало того, что одна и та же машина, я загружаю скрипт в один и тот же сеанс IRB (просто выполняю load "MyScript.rb", а затем вручную создаю экземпляры своих объектов), поэтому между ними не должно быть абсолютно никаких различий в среде. - person glenatron; 08.11.2013
comment
@glenatron, не могли бы вы опубликовать результат p @path после строки @path = ...? (чтобы убедиться, что в пути нет невидимого символа) - person falsetru; 08.11.2013
comment
@falstru Интересно - там написано "/home/glenatron/projects/myJSProject/alice.js\r" - как ты думаешь, что там делает \r? Это половина переноса строки??? - person glenatron; 08.11.2013
comment
@falsetru, что говорит p files? alice.js пришло из этого массива. Так что подозреваю ;) - person falsetru; 08.11.2013
comment
@falstru - это было \r - потому что в моем реальном примере я анализировал имена файлов из другого файла с помощью регулярного выражения, он должен был сохранить половину символа новой строки (возможно, $ соответствовал \n части \r\ n ) и создание имени файла с невидимым символом. name.strip! решил проблему! - person glenatron; 08.11.2013

Из вашего кода, показанного в вопросе, выглядит как end вместо else, например.

 if (! File.exists? @path)
   print "File does not exist!" 
   end   # <------------ This wasn't valid
 File.open( @path ).each do |line|
     @content << line
   end
 end

должно быть

 if (! File.exists? @path)
   print "File does not exist!" 
 else
   File.open( @path ).each do |line|
   @content << line
   end  # THIS end is valid as it ends a `.each` block
 end
person Michael Durrant    schedule 08.11.2013
comment
Хотя это точно, на самом деле это не связано с ответом на вопрос. Тем не менее, ответ был довольно неясен, и его нужно было подробно дразнить... - person glenatron; 09.11.2013