|
|
| |
Perl::Critic::Policy::ValuesAndExpressions::ProhibitFiletest_f(3) |
User Contributed Perl Documentation |
Perl::Critic::Policy::ValuesAndExpressions::ProhibitFiletest_f(3) |
Perl::Critic::Policy::ValuesAndExpressions::ProhibitFiletest_f - don't use the
-f file test
This policy is part of the
"Perl::Critic::Pulp" add-on. It asks you not
to use the "-f" file test because doing so
is usually wrong or unnecessarily restrictive. On that basis this policy is
under the "bugs" theme and medium severity, see "POLICY
THEMES" in Perl::Critic.
- "-f" is not the opposite of "-d"
- If you're traversing a tree and want to distinguish files from directories
to descend into, then "-d" should be
used so device files or named pipes can be processed.
if (-f $filename) { # bad
process ($filename);
} else {
descend ($filename);
}
if (-d $filename) { # better
descend ($filename);
} else {
process ($filename);
}
- "-f" doesn't mean readable/writable/seekable
- Char specials and named pipes are perfectly good for reading and writing,
and char specials can support seeking. Demanding
"-f" is an unnecessary restriction. You
might only ever use ordinary files normally, but there's no need to
prevent someone else running it on a tape drive, /dev/null, etc.
You always have to test each "seek()"
etc for success anyway, and that will tell you if a file is seekable.
seek HANDLE, 123, 0
or die "Cannot seek: $!";
- "-e" is better than "-f"
- A few inflexible functions or operations may not have good "file not
found" behaviour and may force you to check for a file before
invoking. Using "-e" is better than
"-f" since as described above it doesn't
unnecessarily disallow device files.
if (-f $filename) { # bad
require $filename;
}
if (-e $filename) { # better
require $filename;
}
- "-f" before opening is a race condition
- Testing a filename before opening is bad. Any test before opening is
useless because the file can change or be removed in between the test and
the open ("-X" in perlfunc, and "Consider this
carefully" in filetest, note this about
"-r" etc too).
if (-f $filename) { # bad
open HANDLE, '<', $filename
}
If you want to know if the file can be opened then open the
file! The error return from "open()"
must be checked, so a test beforehand only duplicates that, and is an
opportunity to wrongly presume what the system or the user's permissions
can or can't do.
When opening, "ENOENT" will
say if there was no such file, or
"EISDIR" if it's in fact a
directory.
if (! open HANDLE, '<', $filename) { # better
if ($! == POSIX::ENOENT()) {
...
}
}
If you really do want to enquire into the nature of the file,
in order to only accept ordinary files, then open first and
"-f" on the handle. But that's unusual
except for an archiving or backup program.
Incidentally, the error message in $!
is normally the best thing to print. It can be slightly technical, but
its wording will at least be familiar from other programs and is
translated into the user's locale language.
Most uses of "-f" tend to shell script style
code written in Perl. In the shell, it's usually not possible to do better
than such tests (though "-d" or
"-e" are still generally better than
"-f"), but Perl can do the right thing.
A blanket prohibition like this policy is harsh, but is meant as a
building block or at least to make you think carefully whether
"-f" is really right. As always you can
disable "ProhibitFiletest_f" from your
.perlcriticrc in the usual way (see "CONFIGURATION" in
Perl::Critic),
[-ValuesAndExpressions::ProhibitFiletest_f]
Perl::Critic::Pulp, Perl::Critic, "open" in perlfunc,
"ERRNO" in POSIX, Errno, errno(3)
http://user42.tuxfamily.org/perl-critic-pulp/index.html
Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021 Kevin Ryde
Perl-Critic-Pulp is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option) any
later version.
Perl-Critic-Pulp is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.
You should have received a copy of the GNU General Public License
along with Perl-Critic-Pulp. If not, see
<http://www.gnu.org/licenses>.
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |