timbu has asked for the wisdom of the Perl Monks concerning the following question:

A co-worker showed me this code and it didn't work. ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize,$blocks) = stat($file) || print "ERROR: $filename had error: $!\n";

It doesn't work. I believe this is because stat is not a function, but a unary operator which doesn't set a return value.

But ... ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize,$blocks) = stat($file) or print "ERROR: $filename had error: $!\n";

... mostly works. It never will print "Error ....

Can some explain to me what Perl trickery makes it work with 'or' and not with '||'? I assume is has something to do with precedence of the =,||,or, and stat operators.

Replies are listed 'Best First'.
Re: stat question
by Sidhekin (Priest) on Apr 25, 2002 at 20:03 UTC

    This is precedence, yes, but also context. With '||', the right hand side of the (list) assignment is a (list of a single) scalar. stat() performed in scalar context, if it succeeds, is a scalar; if it does not succeed, print will return a scalar. Either way, only $dev is ever set.

    When you use 'or', the list assignment is performed before the 'or', and the right hand side of the assignment is stat(), evaluated in list context — which is probably what you want.

    If stat() fails in list context, it returns the empty list, and so the list assignment evaluates to 0 in the scalar (boolean) context imposed by 'or' — and so print is called on failure, contrary to your statement that it will "never print". (At least here it prints when $file does not exist.)

    BTW, you stat $file, but print $filename. I would hope that $file is a reference to a file handle :-)
    Perhaps more relevant, I notice that $! was not set when I tried to stat a closed filehandle, though the stat failed. Funny.

    The Sidhekin
    print "Just another Perl ${\(trickster and hacker)},"

Re: stat question
by particle (Vicar) on Apr 25, 2002 at 19:43 UTC
    stat is a function (you can look it up in perlfunc.) or and || are operators, and you can look them up in perlop (hint: it's a matter of precedence.)

    ~Particle ;Þ

      In the Programming Perl, 3rd. ed, p. 96, stat is listed as a named unary operator, is that a mistake?

        In the Programming Perl, 3rd. ed, p. 96, stat is listed as a named unary operator, is that a mistake?

        No; rather, a named operator is a function. Or at least, Perl builtin functions are operators; either list operators or named unary operators.

        Take a look at the first section of perlfunc.

        The Sidhekin
        print "Just another Perl ${\(trickster and hacker)},"