I came across this line of code:
if( -f ) { ... }
-f
appears to test whether the filename exists or not, but I am
if (-f
) { ... }
It seems that either I have misunderstood the question, or else everybody else has.
First, let’s make some assumptions.
Let’s assume that you haven’t overloaded all the -X
prefix unary operators (it’s either all of them or none of them),
Let’s also assume that you haven’t overloaded the <>
circumfix iteration operator.
Assuming that both of those two givens given above shoul hold, then the notation
will do a scalar readline(*filename)
— which depends on the value of $/
— and then pass that result back to the filetest operator for subsequent evaluation, usually but not necessarily by way of stat(2). That means that you had best have a filehandle open by the name of filename
for this to work, unless truly deep wizardry is involved.
If will also do this for <$filename>
, except now $filename
is an indirect handle instead of a direct one like filename
. Again, $/
is respected. Using a filename proper for the filehandle associated with it is actually something I do all the term. For example:
our $fn = "/etc/termcap";
open($fn, "<", $fn) || die "can't open $fn: $!";
That way the warn
and die
messages actually tell me the name of the file. For example:
while (<$fh>) {
warn "oops" if whatever;
}
will tell me the line number and the name of the file at which I oopsted.
Now, if the operand of the <⋯>
deviates from the rules for allowed unbraced dative objects, that is, a bareword prefixed by zero or more dollar signs, then it is not the iteration operator but the wildcard burster. This is true even without wildcards. It just has to violate Perl’s famous Rule of Datives, and that then triggers the alternate
This means that if and only if filename
isn’t a legal bareword with zero or more leading dollar signs — such as for example /etc/termcap
, /tmp
, *.[Cchy]
, {,/usr}/bin/c?
, or ~/Documents
— then that familiar old conglobulation operator in the guide of the File::Glob::bsd_glob
function is called instead, with exactly the sort of result you would expect of such a useful and commonly used function when supplied with the appropriate argument.
Here are many examples that show answers to the sort of question the quoted portion above is actually asking:
use v5.10; # for the say feature, but not needed for conglobulation
if (-d <~joebob> ) { say "joebob has a home" }
if (-d <~joebob/.opera> ) { say "joebob has an opera directory" }
if (-d <~joebob/.ssh> ) { say "joebob has an ssh directory" }
if ($n = grep {-e} <~joebob/.*rc>) { say "joebob has $n RC files" }
if (-f <~joebob/.exrc> ) { say "joebob has a vi config file" }
if (-f <~joebob/.profile> ) { say "joebob has a sh profile" }
if (-f <~joebob/.bashrc> ) { say "joebob has a bash config script" }
if (-f <~joebob/.cshrc> ) { say "joebob has a csh config script" }
if (-f <~joebob/.log{in,out}*> ) { say "joebob has csh login/out scripts" }
if (-S ) { say "I smell an X11 socket" }
if (-t STDIN && -t STDOUT ) { say "smells pretty tty to me" }