15

On ruby-doc, the documentation entries for File::exist? and File::exists? are duplicated with different semantics: one entry says returns true if file_name is a directory; the other says returns true if file_name is a file.

I don't think either entry is correct. Both methods seem to be implemented in file.c using rb_file_exist_p, which, seems to try to call fstat() if the value passed is an IO, or stat() if it's a string. Both fstat() and stat() return 0 on success and -1 on error, and this is passed back to rb_file_exist_p, and turned into a boolean result. It seems to me that

  1. there are two methods for making code read more easily; there are no semantic differences
  2. neither really relates to a file existing, but to whether a file-like item exists, e.g. a file, a dir, a socket, a fifo etc.
  3. perhaps the document could say that the methods tell the caller whether or not a thing that has file-like semantics is there, but more specific tests will tell what it actually is: e.g. directory?, file?, socket? etc.

Is my understanding of the (lack of) difference in the methods correct, and is it worth suggesting a change to the document ?

4

4 回答 4

24

请注意,这个问题的答案取决于 Ruby 版本。有关较新版本的 Ruby,请参阅其他答案。AFAIKexists?在 2.2 中已弃用。


如果我们查看 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);

所以File.exist?File.exists?完全一样,相应的文档是:

Return <code>true</code> if the named file exists.

rb_file_exist_pC 函数只是一个非常薄的包装器,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即使Dirdir.c.

根本问题似乎是源代码排列与文档生成器的预期不匹配,结果是混乱和不正确的文档。我不确定这应该如何解决。

于 2013-01-13T06:28:46.777 回答
11

File.exists?由于不推荐使用ruby​​ 2.2.0File.exist?

http://ruby-doc.org/core-2.2.0/File.html#exist-3F-method

于 2017-06-14T10:48:55.950 回答
9

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?

于 2017-09-06T07:08:51.933 回答
2

git pull 让它消失了-这里已修复-不确定为什么在 ruby​​-doc 和 apidock 上生成的 doco 仍然错误

于 2013-01-13T11:14:15.777 回答