I have some code like this:
if (!-d _ || !-o _ || ($vncUserDirUnderTmp && ($mode & 0777) != 0700)) { raise Exception("$prog: Wrong type or access mode of $vncUserDir.\n") }
I could find information about @_
and $_
in Perl but not about _
alone. What does it mean in -d _
and -o _
here?
To improve legibility, Perl allows you to use an underscore character instead. The underscore only works within literal numbers specified in your program, not in strings functioning as numbers or in data read from somewhere else. Similarly, the leading 0x for hex and 0 for octal work only for literals.
$@ The Perl syntax error or routine error message from the last eval, do-FILE, or require command. If set, either the compilation failed, or the die function was executed within the code of the eval.
=~ is the Perl binding operator and can be used to determine if a regular expression match occurred (true or false) $sentence = "The river flows slowly."; if ($sentence =~ /river/) { print "Matched river.\n"; } else { print "Did not match river.\n"; } Follow this answer to receive notifications.
When used with a filetest (-X) operator the stat
structure of the previous file test is used
If any of the file tests (or either the
stat
orlstat
operator) is given the special filehandle consisting of a solitary underline, then thestat
structure of the previous file test (orstat
operator) is used, saving a system call.
...
Example:stat($filename); print "Readable\n" if -r _; print "Writable\n" if -w _; ...
So in your example !-d _
tests whether the file last stat
-ed isn't a directory.
Update
The unusual _
is really a typeglob *_
but with operators expecting a filehandle the *
may be omitted, like <*STDIN>
may be written as <STDIN>
. It is found in the symbol table
print *{$main::{_}}{IO}, "\n"; # --> IO::Handle=IO(0x2311970)
In a one-liner the *_
gets set up only after calls to stat
and _
are made.
When you call one of the file test operators (-f
, -d
, -s
, etc) Perl actually makes a call to the operating system's stat
function. The stat
function returns a structure full of all sorts of interesting information about the file in question, but each of the file test operators only looks at one of the fields from that structure (is it a file? is it a directory? how big is it?)
It's common that you might want to know more that one piece of information about a file (is it a file? can I read it? can I execute it?) The naive way to write that is:
if (-f $file and -r $file and -x $file)
But that makes three calls to stat
- with each one of them only looking at one of the fields from the structure. To mitigate that, Perl is clever and caches the results of the most recent call to stat
. It is cached against the special filehandle _
. So a more efficient way to write the same code is:
if (-f $file and -r _ and -x _)
That only makes one call to stat
.
Since Perl 5.10, you can also use "stacked file tests" and write this code as:
if (-x -r -f $file) # Note reversed order of operators
Update: perldoc says this about stacked file operators.
As of Perl 5.10.0, as a form of purely syntactic sugar, you can stack file test operators, in a way that
-f -w -x $file
is equivalent to"-x $file && -w _ && -f _
. (This is only fancy syntax: if you use the return value of-f $file
as an argument to another filetest operator, no special magic will happen.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With