Разница между "Файл:: существует?" И "Файл:: существует?"
В ruby-doc записи документации для File::exist?
и File::exists?
дублируются с использованием другой семантики: одна запись говорит, возвращает true
если file_name
- это каталог; другой говорит, возвращает true
, если file_name
является файлом.
Я не думаю, что запись верна. Оба метода, похоже, реализованы в file.c
с помощью rb_file_exist_p
, который, кажется, пытается вызвать fstat()
, если переданное значение является IO или stat()
, если это строка. Оба fstat()
и stat()
возвращают 0
при успехе и -1
при ошибке, и это возвращается к rb_file_exist_p
и превращается в логический результат. Мне кажется, что
- существует два способа облегчения чтения кода; нет семантических различий
- ни один из них не связан с существующим файлом, но существует ли файл-подобный элемент, например. файл, директорию, сокет, fifo и т.д.
- Возможно, документ может сказать, что методы сообщают вызывающему, есть ли вещь, которая имеет файловую семантику, но более конкретные тесты расскажут, что это на самом деле: например. каталог?, файл?, сокет? и др.
Насколько я понимаю (недостаток) разницы в методах, и стоит ли предлагать изменение документа?
Ответы
Ответ 1
Обратите внимание, что ответ на этот вопрос зависит от версии Ruby. См. Другие ответы для более новых версий Ruby.
Если мы посмотрим на источник C, мы увидим это:
rb_cFile = rb_define_class("File", rb_cIO);
/* ... */
define_filetest_function("exist?", rb_file_exist_p, 1);
define_filetest_function("exists?", rb_file_exist_p, 1);
So File.exist?
и File.exists?
- это точно то же самое, и соответствующая документация:
Return <code>true</code> if the named file exists.
Функция rb_file_exist_p
C - это очень тонкая оболочка rb_stat
, которая является оболочкой для макроса STAT
и STAT
- это просто переносимость для системного вызова STAT
. Итак, приведенная выше документа верна: File#exist?
возвращает true
, если файл существует.
Если мы проверим file.c
для фрагмента документации, который говорит о каталогах, мы найдем это:
/*
* Document-method: exist?
*
* call-seq:
* Dir.exist?(file_name) -> true or false
* Dir.exists?(file_name) -> true or false
*
* Returns <code>true</code> if the named file is a directory,
* <code>false</code> otherwise.
*
*/
Итак, похоже, что генератор документации запутывается, потому что Dir.exist?
и File.exist?
задокументированы в file.c
, хотя Dir
определен в dir.c
.
Основная проблема заключается в том, что компоновка исходного кода не соответствует ожидаемому генератору документации, а результат запутан и неправильная документация. Я не уверен, как это должно быть исправлено.
Ответ 2
Так как ruby 2.2.0 File.exists?
используется вместо устаревшего File.exist?
http://ruby-doc.org/core-2.2.0/File.html#exist-3F-method
Ответ 3
File.exist?
и File.exists?
больше не то же самое. См. https://github.com/ruby/ruby/blob/ruby_2_3/file.c#L5920
define_filetest_function("exist?", rb_file_exist_p, 1);
define_filetest_function("exists?", rb_file_exists_p, 1);
rb_file_exists_p
содержит следующую строку:
rb_warning("%sexists? is a deprecated name, use %sexist? instead", s, s);
Итак, вы должны придерживаться File.exist?
.
Ответ 4
git pull заставило его уйти - это было исправлено здесь - не знаю, почему сгенерированное doco на ruby-doc и apidock все еще не так