.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Perl::Critic::Policy::ValuesAndExpressions::ProhibitFiletest_f 3pm" .TH Perl::Critic::Policy::ValuesAndExpressions::ProhibitFiletest_f 3pm "2021-02-28" "perl v5.32.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Perl::Critic::Policy::ValuesAndExpressions::ProhibitFiletest_f \- don't use the \-f file test .SH "DESCRIPTION" .IX Header "DESCRIPTION" This policy is part of the \f(CW\*(C`Perl::Critic::Pulp\*(C'\fR add-on. It asks you not to use the \f(CW\*(C`\-f\*(C'\fR file test because doing so is usually wrong or unnecessarily restrictive. On that basis this policy is under the \*(L"bugs\*(R" theme and medium severity, see \*(L"\s-1POLICY THEMES\*(R"\s0 in Perl::Critic. .ie n .IP """\-f"" is not the opposite of ""\-d""" 4 .el .IP "\f(CW\-f\fR is not the opposite of \f(CW\-d\fR" 4 .IX Item "-f is not the opposite of -d" If you're traversing a tree and want to distinguish files from directories to descend into, then \f(CW\*(C`\-d\*(C'\fR should be used so device files or named pipes can be processed. .Sp .Vb 5 \& if (\-f $filename) { # bad \& process ($filename); \& } else { \& descend ($filename); \& } \& \& if (\-d $filename) { # better \& descend ($filename); \& } else { \& process ($filename); \& } .Ve .ie n .IP """\-f"" doesn't mean readable/writable/seekable" 4 .el .IP "\f(CW\-f\fR doesn't mean readable/writable/seekable" 4 .IX Item "-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(CW\*(C`\-f\*(C'\fR 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, \fI/dev/null\fR, etc. You always have to test each \f(CW\*(C`seek()\*(C'\fR etc for success anyway, and that will tell you if a file is seekable. .Sp .Vb 2 \& seek HANDLE, 123, 0 \& or die "Cannot seek: $!"; .Ve .ie n .IP """\-e"" is better than ""\-f""" 4 .el .IP "\f(CW\-e\fR is better than \f(CW\-f\fR" 4 .IX Item "-e is better than -f" A few inflexible functions or operations may not have good \*(L"file not found\*(R" behaviour and may force you to check for a file before invoking. Using \&\f(CW\*(C`\-e\*(C'\fR is better than \f(CW\*(C`\-f\*(C'\fR since as described above it doesn't unnecessarily disallow device files. .Sp .Vb 3 \& if (\-f $filename) { # bad \& require $filename; \& } \& \& if (\-e $filename) { # better \& require $filename; \& } .Ve .ie n .IP """\-f"" before opening is a race condition" 4 .el .IP "\f(CW\-f\fR before opening is a race condition" 4 .IX Item "-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 (\*(L"\-X\*(R" in perlfunc, and \*(L"Consider this carefully\*(R" in filetest, note this about \f(CW\*(C`\-r\*(C'\fR etc too). .Sp .Vb 3 \& if (\-f $filename) { # bad \& open HANDLE, \*(Aq<\*(Aq, $filename \& } .Ve .Sp If you want to know if the file can be opened then open the file! The error return from \f(CW\*(C`open()\*(C'\fR 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. .Sp When opening, \f(CW\*(C`ENOENT\*(C'\fR will say if there was no such file, or \f(CW\*(C`EISDIR\*(C'\fR if it's in fact a directory. .Sp .Vb 5 \& if (! open HANDLE, \*(Aq<\*(Aq, $filename) { # better \& if ($! == POSIX::ENOENT()) { \& ... \& } \& } .Ve .Sp 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(CW\*(C`\-f\*(C'\fR on the handle. But that's unusual except for an archiving or backup program. .Sp Incidentally, the error message in \f(CW$!\fR 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. .SS "Disabling" .IX Subsection "Disabling" Most uses of \f(CW\*(C`\-f\*(C'\fR tend to shell script style code written in Perl. In the shell, it's usually not possible to do better than such tests (though \f(CW\*(C`\-d\*(C'\fR or \f(CW\*(C`\-e\*(C'\fR are still generally better than \f(CW\*(C`\-f\*(C'\fR), but Perl can do the right thing. .PP 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(CW\*(C`\-f\*(C'\fR is really right. As always you can disable \f(CW\*(C`ProhibitFiletest_f\*(C'\fR from your \fI.perlcriticrc\fR in the usual way (see \*(L"\s-1CONFIGURATION\*(R"\s0 in Perl::Critic), .PP .Vb 1 \& [\-ValuesAndExpressions::ProhibitFiletest_f] .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" Perl::Critic::Pulp, Perl::Critic, \&\*(L"open\*(R" in perlfunc, \&\*(L"\s-1ERRNO\*(R"\s0 in \s-1POSIX\s0, Errno, \&\fBerrno\fR\|(3) .SH "HOME PAGE" .IX Header "HOME PAGE" http://user42.tuxfamily.org/perl\-critic\-pulp/index.html .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Kevin Ryde .PP Perl-Critic-Pulp is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. .PP Perl-Critic-Pulp is distributed in the hope that it will be useful, but \&\s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of \s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0 See the \s-1GNU\s0 General Public License for more details. .PP You should have received a copy of the \s-1GNU\s0 General Public License along with Perl-Critic-Pulp. If not, see .