Perl::...test_f(3pm)
π Perl::...test_f(3pm) π
okay bestie, so this is a page from the User Contributed Perl Documentation, and it's giving "your Perl::Critic is about to be SO real with you" energy. welcome to the group chat π
β¨ NAME β¨
Perl::Critic::Policy::ValuesAndExpressions::ProhibitFiletest_f β bestie... don't use the -f file test. like, at all. it's a whole thing. π«Ά
πΈ DESCRIPTION πΈ
so this policy lives inside the Perl::Critic::Pulp add-on π and it's politely but firmly asking you to NOT use the -f file test, because using it is usually wrong or unnecessarily restrictive. on that basis it's filed under the "bugs" theme with medium severity β go peek at "POLICY THEMES" in Perl::Critic if you wanna know more about that whole system.
π -f is not the opposite of -d
okay so imagine you're traversing a tree π³ and you wanna tell files apart from directories so you know what to descend into. the move is -d, bestie. use -d. because that way device files and named pipes can still get processed too!!
if (-f $filename) { # bad
process ($filename);
} else {
descend ($filename);
}
if (-d $filename) { # better
descend ($filename);
} else {
process ($filename);
}
like... look at that glow-up. β¨
π₯ -f doesn't mean readable/writable/seekable
char specials and named pipes? perfectly good for reading AND writing, no cap. and char specials can even support seeking!! so demanding -f is just an unnecessary restriction, periodt.
like yeah, maybe you only ever use ordinary files normally, but there's literally no need to prevent someone else from running your code on a tape drive, /dev/null, etc. π and anyway you always have to test each seek() etc for success regardless, and that test will tell you if a file is seekable. so like... skip the extra step.
seek HANDLE, 123, 0
or die "Cannot seek: $!";
π¦ -e is better than -f
some inflexible functions or operations just don't have good "file not found" behaviour π and they may force you to check for a file before invoking them. in that case, use -e instead of -f, because as we just said above, it doesn't unnecessarily disallow device files. iconic behaviour honestly.
if (-f $filename) { # bad
require $filename;
}
if (-e $filename) { # better
require $filename;
}
π -f before opening is a race condition
testing a filename before opening it? bad. literally any test before opening is useless because the file can change or be removed in between the test and the open β this is documented in "-X" in perlfunc and "Consider this carefully" in filetest, and they note the same thing about -r etc too. so yeah. it's giving race condition. it's giving flop.
if (-f $filename) { # bad
open HANDLE, '<', $filename
}
if you wanna know whether the file can be opened... open the file!! π€ the error return from open() must be checked anyway, so testing beforehand only duplicates that work and gives you an opportunity to wrongly presume what the system or the user's permissions can or can't do. not the vibe.
and when you open it, ENOENT will tell you if there was no such file, or EISDIR if it's actually a directory. the system already has receipts π
if (! open HANDLE, '<', $filename) { # better
if ($! == POSIX::ENOENT()) {
...
}
}
if you really truly wanna enquire into the nature of the file, like to only accept ordinary files, then open first and do -f on the handle. but that's unusual β except for an archiving or backup program. so iykyk. π
oh and incidentally? the error message in $! is normally the best thing to print. it can be a little technical ngl, but its wording will at least be familiar from other programs and it's translated into the user's locale language. so like... free localization, slay. π
π Disabling
most uses of -f tend to be shell script style code that someone wrote in Perl. and 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, so let it. π
a blanket prohibition like this policy is harsh, bestie, no lies detected. but it's meant as a building block, or at least to make you think carefully about whether -f is really right. and as always, you can disable ProhibitFiletest_f from your .perlcriticrc in the usual way β see "CONFIGURATION" in Perl::Critic:
[-ValuesAndExpressions::ProhibitFiletest_f]
π SEE ALSO π
Perl::Critic::Pulp, Perl::Critic, "open" in perlfunc, "ERRNO" in POSIX, Errno, errno(3)
πΈ HOME PAGE πΈ
http://user42.tuxfamily.org/perl-critic-pulp/index.html
π COPYRIGHT π
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.
okay that's the whole page, you ate it up bestie π«Ά this was perl v5.40.1, dated 2025-10-21, and yeah the header and footer both said Perl::...test_f(3pm) because that's just how it do. mwah πβ¨
π¦ where this page comes from
- ubuntu resolute: libperl-critic-pulp-perl 100-1 Β· GPL-3.0-or-later
- ubuntu stonking: libperl-critic-pulp-perl 100-1 Β· GPL-3.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms