http://www.perlmonks.org?node_id=1003592


in reply to Re^3: Split output by tabs
in thread Split output by tabs

I disagree as to the bogosity of this practice. There is nothing wrong with adding clarity to a statement that may otherwise be confusing or ambiguous. And there is nothing wrong with reducing the number of rules someone needs to know in order to correctly decipher a statement.

This is just such a case, because an argument given to print can start with either a filehandle or a variable. Depending on what follows, it can be very hard to tell which is intended without braces.

I do enjoy how Perl lets one push the boundaries of acceptable syntax, but that doesn't mean it's always a good idea to do so. That's just my opinion, of course.



When's the last time you used duct tape on a duct? --Larry Wall

Replies are listed 'Best First'.
Re^5: Split output by tabs
by Anonymous Monk on Nov 13, 2012 at 13:45 UTC

    There is nothing wrong with adding clarity to a statement that may otherwise be confusing or ambiguous. And there is nothing wrong with reducing the number of rules someone needs to know in order to correctly decipher a statement.

    How does it add clarity or reduce the number or rules?

    perldoc -f print starts with

    print FILEHANDLE LIST
    print FILEHANDLE
    print LIST

    print { EXPR } LIST is not on the list at all

    Where is the ambiguity?

    print $fh map { "$_\n" } @list; print {$fh} map { "$_\n" } @list; $fh->print( map { "$_\n" } @list ); print( $fh map { "$_\n" } @list ); print( {$fh} map { "$_\n" } @list ); print $fh @list; print {$fh} @list; $fh->print( @list ); print( $fh @list ); print( {$fh} @list );

    This is just such a case, because an argument given to print can start with either a filehandle or a variable. Depending on what follows, it can be very hard to tell which is intended without braces.

    They're both called filehandles, both STDOUT and $fh, the first argument to print is always an optional filehandle followed by a LIST

    STDOUT is a bareword filehandle and $fh is a lexical-scalar filehandle

      And now try it with
      my %handle = ( out => *STDOUT, err => *STDERR ); print {$handle{out}} "Test\n"; # Not possible without braces.
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
        And now try it with
        my %handle = ( out => *STDOUT, err => *STDERR ); print {$handle{out}} "Test\n"; # Not possible without braces.

        This is one of the rare cases, in which a BLOCK (which returns a file handle) is needed. For such a rare case, which anyways would have better been written as

        my %handle = ( out => *STDOUT, err => *STDERR ); my $fh = $handle{out}; print $fh "Test\n"; # Look, ma! no curlies at all.

        the appropriate syntax is glorified as "Best Practice"! Oh my.

        Why? An exception does not make the rule

      I do understand the syntax of Perl filehandles. The ambiguity comes between printing to a filehandle and printing a variable to STDOUT. i.e.:

      open my $f, '>out.txt' or die 'ouch!'; print $f 'foo'; ... my $f = 'bar'; print $f, 'foo';

      These two similar looking print statements do something very different. It is not a big deal in this case, but when you replace 'foo' with an expression it can be hard to tell whether $f is a filehandle or a variable. In fact, sometimes even the interpreter can't tell, as the documentation you linked to points out:

      (NOTE: If FILEHANDLE is a variable and the next token is a term, it may be misinterpreted as an operator unless you interpose a + or put parentheses around the arguments.)

      Here is a simple example that the compiler can't correctly handle without braces:

      use warnings; use strict; open my $f, '>out.txt' or die 'ouch!'; $_=' eeee'; my $e='e'; #supposed to be a pattern match, but interpreted as division. print $f / $e/ ? 'yes' : 'no';


      When's the last time you used duct tape on a duct? --Larry Wall
        The ambiguity comes between printing to a filehandle and printing a variable to STDOUT. i.e.:

        That ambiguity is not solved by a "Best Practice", since it persists; the so-called "Best Practice" obscures knowledge and doesn't catch all type of errors.

        $f = "foo"; # (1) # ... # time passes... (2) # ... print {$f} bar; # (3)

        Here, the poor practice is, in the first place, using a meaningless single letter as a variable identifier. Second, to allow for actions at a distance using that variable. Third, not checking for the success of print which a) goes to a symbolic bareword filehandle reference (bad!) and b) most likely to a closed file handle.

        These are the real problems here, and not the use or omission of curlies around every file handle expression.

        And, again: it is better to know about ambiguities and how to handle them, instead of adhering to a "Best Practice" in a futile attempt to avoid them.

        Think language.

        you replace 'foo' with an expression it can be hard to tell whether $f is a filehandle or a variable.

        Nope, it is never a "filehandle" , there is no ambiguity

        Here is a simple example that the compiler can't correctly handle without braces:

        Sure it can, and it does (v5.14).

        all you need for disambiguation is M as in m//

        I don't know what exact justifications TheDamian gives in the book, but I highly doubt its because of that contrived example -- highly flimsy justification for such an obnoxious rule