Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re^5: Split output by tabs

by Anonymous Monk
on Nov 13, 2012 at 13:45 UTC ( #1003611=note: print w/ replies, xml ) Need Help??


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

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


Comment on Re^5: Split output by tabs
Download Code
Re^6: Split output by tabs
by choroba (Abbot) on Nov 13, 2012 at 13:58 UTC
    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
Re^6: Split output by tabs
by ColonelPanic (Friar) on Nov 13, 2012 at 14:13 UTC

    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.

        The single-letter variable was for the purposes of the example. The example still holds with a more descriptive name--is $results_file a filehandle or a string containing the name of a file?

        More knowledge about the ambiguities of Perl is always a good thing. I don't see this practice as a replacement for knowing how things work. It just adds clarity. Braces are a nice visual cue that make a filehandle variable instantly recognizable as a filehandle.



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

      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

        Yes, there are multiple ways to get that statement to work. You could also use parentheses, do your logic beforehand and put it in a variable, or write the code in countless other ways.

        But it still proves that in some cases even the compiler can't tell whether there is a filehandle (ok, ok, a variable containing a filehandle reference) or an ordinary variable at the start of a print statement.

        This may be a single contrived example (though it is nothing unusual really), but the set of cases in which the statement will not be clear to the human eye is much larger.



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

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1003611]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (12)
As of 2014-11-28 10:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (195 votes), past polls