Project

General

Profile

Actions

Bug #10067

closed

File.file? misleading semantics & documentation for symbolic links

Added by robe (Michael Renner) over 10 years ago. Updated over 10 years ago.

Status:
Closed
Assignee:
Target version:
ruby -v:
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]
[ruby-core:63842]

Description

The documentation for File.file? states:

"Returns true if the named file exists and is a regular file."

When trying that out I get the following results:

% /usr/bin/stat link
  File: `link' -> `file'
  Size: 4         	Blocks: 0          IO Block: 4096   symbolic link
Device: 16h/22d	Inode: 2804357     Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/    robe)   Gid: ( 1000/    robe)
Access: 2014-07-19 01:01:51.514979670 +0200
Modify: 2014-07-19 01:01:50.799975936 +0200
Change: 2014-07-19 01:01:50.799975936 +0200
 Birth: -
% ruby -e "puts File.file?('link')"
false
% ruby -e "puts File.symlink?('link')"
true
% touch file
% ruby -e "puts File.file?('link')"
true
% ruby -e "puts File.symlink?('link')"
true
%

which is entirely not what one would expect.

You need to decide if the File ?-methods offer stat OR lstat semantic, change it and document it accordingly.

The current documentation and implementation behavior is especially confusing since the POSIX standard states that the type of a file can be either a regular file OR a symlink, not both at the same time.

Updated by nobu (Nobuyoshi Nakada) over 10 years ago

  • Category changed from core to doc
  • Assignee set to zzak (zzak _)
  • Target version set to 2.2.0

It's same as test(1) command.

Updated by jaredbeck (Jared Beck) over 10 years ago

I can confirm that test -f and File.file? seem to have the same return values in this example:

ln -s link file
ruby -e 'puts File.file?("link")'
false
test -f link; echo $?
1
touch file
ruby -e 'puts File.file?("link")'
true
test -f link; echo $?
0

Though, I'm using ruby 2.1.2 on mac os 10.9.4, so your mileage may vary :)

ruby --version
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]

Updated by nobu (Nobuyoshi Nakada) over 10 years ago

Citing from POSIX manpage test(1)

With the exception of the -h pathname and -L pathname primaries,
if a pathname argument is a symbolic link, test shall evaluate the
expression by resolving the symbolic link and using the file
referenced by the link.

Updated by robe (Michael Renner) over 10 years ago

Nobuyoshi Nakada wrote:

Citing from POSIX manpage test(1)

With the exception of the -h pathname and -L pathname primaries,
if a pathname argument is a symbolic link, test shall evaluate the
expression by resolving the symbolic link and using the file
referenced by the link.

Oh my, just double-checked, Python and Perl have implemented the same behaviour as test(1), along with Ruby.

The big difference being the wording of the documentation. The test man page explicitly states:

True if pathname resolves to an existing directory entry for a [..]

as well as the paragraph you quoted.

I guess clarifying that in the File documentation is warranted as well as pointing out that people are strongly advised to use lstat if they want consistent behaviour.

I personally would go as far and ditch the test(1) semantics and stick to querying lstat() by default, but that's just me and will probably break lots of things ;)

Updated by zzak (zzak _) over 10 years ago

  • Status changed from Open to Assigned

Thanks, I'll see if I can clean up any misunderstandings here

Updated by zzak (zzak _) over 10 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

Applied in changeset r46978.


  • file.c: [DOC] Clarify how File.file? handles symbolic links. Also
    cleaned up the rdoc style for this method, more to follow.
    Originally reported by Michael Renner [Bug #10067]
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0