Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^6: Split output by tabs

by ColonelPanic (Friar)
on Nov 13, 2012 at 14:13 UTC ( #1003619=note: print w/ replies, xml ) Need Help??


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

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


Comment on Re^6: Split output by tabs
Select or Download Code
Re^7: Split output by tabs (bogus best practice)
by shmem (Canon) on Nov 13, 2012 at 14:48 UTC
    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
        Braces are a nice visual cue that make a filehandle variable instantly recognizable as a filehandle.

        Guessed that I could whip up an example where it isn't?

        qwurx [shmem] ~ > perl -le '$h = {foo => "42"}; print {$h} "foo"' Not a GLOB reference at -e line 1. qwurx [shmem] ~ >

        Aha.

        sort {byid} @list; map {$_->()} @stuff; print {$fh||$ofh} @vars;

        Braces are no nice visual cue! They mean and do something. Using them uncalled for is either decorative or cargo cult programming.

        Note that I'm not averse to the odd drink which is style, I just don't call "best practice" any blurf which doesn't hold water.

Re^7: Split output by tabs
by Anonymous Monk on Nov 13, 2012 at 15:01 UTC

    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

        But it still proves that ...

        Which is a point that did not need proving, and is not a justification for for rule 136

        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.

        No it isn't

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2014-07-26 13:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (176 votes), past polls