Perl

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • perlopentut.pod start recommenting $fh instead of FH

    9 answers - 214 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    "Gabor Szabo" <szabgab (AT) gmail (DOT) comwrites:
    + print $out "Say something nice\n";
    Shouldn't this be
    print {$out} "Say something nice\n";
    As per PBP?
    -- Johan
  • No.1 | | 7618 bytes | |

    Fri, 14 Jul 2006 13:27:32 +0300, "Gabor Szabo" <szabgab (AT) gmail (DOT) comwrote:

    pod/perlopentut.pod.orig 2006-07-14 12:28:40.000000000 +0300
    pod/perlopentut.pod 2006-07-14 13:26:54.000000000 +0300
    @@ -2,6 +2,37 @@ =head1 NAME

    perlopentut - tutorial on opening things in Perl

    +=head1 Reading a file
    +
    +A few examples for the unpatient:
    +
    +Reading a file line by line:
    +
    + open my $fh, "<", "data.txt" or die "Could not open data.txt: $!";
    + while (my $line = <$fh>) {

    Is there a good reason you insist on using this?
    And *if* you are using this, do it correct:

    while (defined (my $line = <$fh>)) {

    You are making up examples here for the inpatient,
    why not just use what we all use

    open my $fh, "<", "data.txt" or die "Could not open data.txt: $!";
    while (<$fh>) {
    chomp; # strip optional trailing $/
    # more processing on $_
    }

    + # chomp $line; # to get rid of trailing \n
    + # do something with $line
    + }
    +
    +If the name of the file is in a variable $filename :
    +
    + open my $fh, "<", $filename or die "Could not open $filename: $!";
    + while (my $line = <$fh>) {
    + # chomp $line; # to get rid of trailing \n
    + # do something with $line
    + }
    +
    +To write to a file:
    +
    + open my $out, ">", "outfile.txt" or die "Could not open outfile.txt: $!";
    + print $out "Say something nice\n";
    +
    +To append to a file:
    +
    + open my $out, ">>", "outfile.txt" or die "Could not open outfile.txt: $!";
    + print $out "Add something nice\n";
    +
    +
    =head1 DESCRIPTIN

    Perl has two simple, built-in ways to open files: the shell way for
    @@ -35,67 +66,63 @@ =head1 E<agravela shell

    =head2 Simple
    -The C<openfunction takes two arguments: the first is a filehandle,
    -and the second is a single string comprising both what to open and how
    -to open it. C<openreturns true when it works, and when it fails,
    -returns a false value and sets the special variable C<$!to reflect
    -the system error. If the filehandle was previously opened, it will
    -be implicitly closed first.
    +The C<openfunction takes three arguments: the first is a filehandle,
    +the second is the mode (how to open) and the third is a single string
    +containing what to open. C<openreturns true when it works. When it
    +fails, returns a false value and sets the special variable C<$!to
    +reflect the system error. If the filehandle was previously opened,
    +it will be implicitly closed first.

    For example:
    - open(INF, "datafile") || die("can't open datafile: $!");
    - open(INF, "< datafile") || die("can't open datafile: $!");
    - open(RESULTS,"runstats") || die("can't open runstats: $!");
    - open(LG, ">logfile ") || die("can't open logfile: $!");
    + open(my $info, "<", "datafile") || die("can't open datafile: $!");
    + open(my $results,">", "runstats") || die("can't open runstats: $!");
    + open(my $log, ">>", "logfile") || die("can't open logfile: $!");

    I suggest to drop the above sample completely and just push the low
    punctuation version here. It's a tutorial on open, not on syntax TIMTWTDI

    If you prefer the low-punctuation version, you could write that this way:
    - open INF, "< datafile" or die "can't open datafile: $!";
    - open RESULTS,"runstats" or die "can't open runstats: $!";
    - open LG, ">logfile " or die "can't open logfile: $!";
    + open my $info, "<", "datafile" or die "can't open datafile: $!";
    + open my $results,">", "runstats" or die "can't open runstats: $!";
    + open my $log, ">>", "logfile" or die "can't open logfile: $!";
    -A few things to notice. First, the leading less-than is optional.
    -If omitted, Perl assumes that you want to open the file for reading.
    + thing to notice:
    -Note also that the first example uses the C<||logical operator, and the
    -second uses C<or>, which has lower precedence. Using C<||in the latter
    +The first set of examples use the C<||logical operator, and the second
    +set uses C<or>, which has lower precedence. Using C<||in the latter
    examples would effectively mean

    That could then be a warning not to use the ||
    - open INF, ( "< datafile" || die "can't open datafile: $!" );
    + open my $info, "<", ( "datafile" || die "can't open datafile: $!" );

    which is definitely not what you want.
    -The other important thing to notice is that, just as in the shell,
    -any whitespace before or after the filename is ignored. This is good,
    -because you wouldn't want these to do different things:
    +For accessing files with naughty names, see L<"Dispelling the Dweomer">.
    - open INF, "<datafile"
    - open INF, "< datafile"
    - open INF, "< datafile"
    +For backward compability with Perls before 5.6 there is also a 2-argument
    +version of C<open>, which requires you attach the special redirection
    +characters to the beginning of the thing to be opened:
    -Ignoring surrounding whitespace also helps for when you read a filename
    -in from a different file, and forget to trim it before opening:
    + open( my $info, ">$datafile" ) || die "Can't create $datafile: $!";
    + open( my $info, "<$datafile" ) || die "Can't open $datafile: $!";
    + open( my $info, "$inputfile" ) || die "Can't open $inputfile: $!";

    or instead of ||
    - $filename = <INF>; # oops, \n still there
    - open(EXTRA, "< $filename") || die "can't open $filename: $!";
    +Note, in this version the leading less-than is optional, but it is not
    +recommended to leave it out. If omitted, Perl normally assumes that you
    +want to open the file for reading.
    -This is not a bug, but a feature. Because C<openmimics the shell in
    -its style of using redirection arrows to specify how to open the file, it
    -also does so with respect to extra whitespace around the filename itself
    -as well. For accessing files with naughty names, see
    -L<"Dispelling the Dweomer">.
    + the other hand if the value of $inputfile was received from an external
    +source and if for some reason the name given includes a leading grater-than
    +sign then the file will be opened for writing. Certainly not what you wanted.
    +Leaving out the leading less-than sign can create a security hole in your code.
    -There is also a 3-argument version of C<open>, which lets you put the
    -special redirection characters into their own argument:
    +In addition for backward compability with Perl before 5.6.0, one can
    +use bare words as filehandles:
    - open( INF, ">", $datafile ) || die "Can't create $datafile: $!";
    + open( INF, ">$datafile" ) || die "Can't create $datafile: $!";

    same.

    +
    +This is not a recommended practice any more as it has several drawbacks
    +such as being INF being global to the whole application and being
    +very hard to pass as argument to a function.
    -In this case, the filename to open is the actual string in C<$datafile>,
    -so you don't have to worry about C<$datafilecontaining characters
    -that might influence the open mode, or whitespace at the beginning of
    -the filename that would be absorbed in the 2-argument version. Also,
    -any reduction of unnecessary string interpolation is a good thing.

    =head2 Indirect Filehandles
  • No.2 | | 6864 bytes | |

    pod/perlopentut.pod.orig 2006-07-14 12:28:40.000000000 +0300
    pod/perlopentut.pod 2006-07-14 13:26:54.000000000 +0300
    @@ -2,6 +2,37 @@ =head1 NAME

    perlopentut - tutorial on opening things in Perl

    +=head1 Reading a file
    +
    +A few examples for the unpatient:
    +
    +Reading a file line by line:
    +
    + open my $fh, "<", "data.txt" or die "Could not open data.txt: $!";
    + while (my $line = <$fh>) {
    + # chomp $line; # to get rid of trailing \n
    + # do something with $line
    + }
    +
    +If the name of the file is in a variable $filename :
    +
    + open my $fh, "<", $filename or die "Could not open $filename: $!";
    + while (my $line = <$fh>) {
    + # chomp $line; # to get rid of trailing \n
    + # do something with $line
    + }
    +
    +To write to a file:
    +
    + open my $out, ">", "outfile.txt" or die "Could not open outfile.txt: $!";
    + print $out "Say something nice\n";
    +
    +To append to a file:
    +
    + open my $out, ">>", "outfile.txt" or die "Could not open outfile.txt: $!";
    + print $out "Add something nice\n";
    +
    +
    =head1 DESCRIPTIN

    Perl has two simple, built-in ways to open files: the shell way for
    @@ -35,67 +66,63 @@ =head1 E<agravela shell

    =head2 Simple
    -The C<openfunction takes two arguments: the first is a filehandle,
    -and the second is a single string comprising both what to open and how
    -to open it. C<openreturns true when it works, and when it fails,
    -returns a false value and sets the special variable C<$!to reflect
    -the system error. If the filehandle was previously opened, it will
    -be implicitly closed first.
    +The C<openfunction takes three arguments: the first is a filehandle,
    +the second is the mode (how to open) and the third is a single string
    +containing what to open. C<openreturns true when it works. When it
    +fails, returns a false value and sets the special variable C<$!to
    +reflect the system error. If the filehandle was previously opened,
    +it will be implicitly closed first.

    For example:
    - open(INF, "datafile") || die("can't open datafile: $!");
    - open(INF, "< datafile") || die("can't open datafile: $!");
    - open(RESULTS,"runstats") || die("can't open runstats: $!");
    - open(LG, ">logfile ") || die("can't open logfile: $!");
    + open(my $info, "<", "datafile") || die("can't open datafile: $!");
    + open(my $results,">", "runstats") || die("can't open runstats: $!");
    + open(my $log, ">>", "logfile") || die("can't open logfile: $!");

    If you prefer the low-punctuation version, you could write that this way:
    - open INF, "< datafile" or die "can't open datafile: $!";
    - open RESULTS,"runstats" or die "can't open runstats: $!";
    - open LG, ">logfile " or die "can't open logfile: $!";
    + open my $info, "<", "datafile" or die "can't open datafile: $!";
    + open my $results,">", "runstats" or die "can't open runstats: $!";
    + open my $log, ">>", "logfile" or die "can't open logfile: $!";
    -A few things to notice. First, the leading less-than is optional.
    -If omitted, Perl assumes that you want to open the file for reading.
    + thing to notice:
    -Note also that the first example uses the C<||logical operator, and the
    -second uses C<or>, which has lower precedence. Using C<||in the latter
    +The first set of examples use the C<||logical operator, and the second
    +set uses C<or>, which has lower precedence. Using C<||in the latter
    examples would effectively mean
    - open INF, ( "< datafile" || die "can't open datafile: $!" );
    + open my $info, "<", ( "datafile" || die "can't open datafile: $!" );

    which is definitely not what you want.
    -The other important thing to notice is that, just as in the shell,
    -any whitespace before or after the filename is ignored. This is good,
    -because you wouldn't want these to do different things:
    +For accessing files with naughty names, see L<"Dispelling the Dweomer">.
    - open INF, "<datafile"
    - open INF, "< datafile"
    - open INF, "< datafile"
    +For backward compability with Perls before 5.6 there is also a 2-argument
    +version of C<open>, which requires you attach the special redirection
    +characters to the beginning of the thing to be opened:
    -Ignoring surrounding whitespace also helps for when you read a filename
    -in from a different file, and forget to trim it before opening:
    + open( my $info, ">$datafile" ) || die "Can't create $datafile: $!";
    + open( my $info, "<$datafile" ) || die "Can't open $datafile: $!";
    + open( my $info, "$inputfile" ) || die "Can't open $inputfile: $!";
    - $filename = <INF>; # oops, \n still there
    - open(EXTRA, "< $filename") || die "can't open $filename: $!";
    +Note, in this version the leading less-than is optional, but it is not
    +recommended to leave it out. If omitted, Perl normally assumes that you
    +want to open the file for reading.
    -This is not a bug, but a feature. Because C<openmimics the shell in
    -its style of using redirection arrows to specify how to open the file, it
    -also does so with respect to extra whitespace around the filename itself
    -as well. For accessing files with naughty names, see
    -L<"Dispelling the Dweomer">.
    + the other hand if the value of $inputfile was received from an external
    +source and if for some reason the name given includes a leading grater-than
    +sign then the file will be opened for writing. Certainly not what you wanted.
    +Leaving out the leading less-than sign can create a security hole in your code.
    -There is also a 3-argument version of C<open>, which lets you put the
    -special redirection characters into their own argument:
    +In addition for backward compability with Perl before 5.6.0, one can
    +use bare words as filehandles:
    - open( INF, ">", $datafile ) || die "Can't create $datafile: $!";
    + open( INF, ">$datafile" ) || die "Can't create $datafile: $!";
    +
    +This is not a recommended practice any more as it has several drawbacks
    +such as being INF being global to the whole application and being
    +very hard to pass as argument to a function.
    -In this case, the filename to open is the actual string in C<$datafile>,
    -so you don't have to worry about C<$datafilecontaining characters
    -that might influence the open mode, or whitespace at the beginning of
    -the filename that would be absorbed in the 2-argument version. Also,
    -any reduction of unnecessary string interpolation is a good thing.

    =head2 Indirect Filehandles
  • No.3 | | 2494 bytes | |

    Fri, Jul 14, 2006 at 01:27:32PM +0300, Gabor Szabo wrote:
    pod/perlopentut.pod.orig 2006-07-14 12:28:40.000000000 +0300
    pod/perlopentut.pod 2006-07-14 13:26:54.000000000 +0300
    @@ -2,6 +2,37 @@ =head1 NAME

    perlopentut - tutorial on opening things in Perl

    +=head1 Reading a file

    "Reading a file" is not a proper =head1 label (and doesn't accurately
    describe this new section anyway). I think putting these in the
    DESCRIPTIN with a =head2 Quick Examples heading would be better.

    +
    +A few examples for the unpatient:

    s/unpatient/impatient/

    +
    +Reading a file line by line:
    +
    + open my $fh, "<", "data.txt" or die "Could not open data.txt: $!";
    + while (my $line = <$fh>) {
    + # chomp $line; # to get rid of trailing \n
    + # do something with $line
    + }
    +
    +If the name of the file is in a variable $filename :
    +
    + open my $fh, "<", $filename or die "Could not open $filename: $!";
    + while (my $line = <$fh>) {
    + # chomp $line; # to get rid of trailing \n
    + # do something with $line
    + }

    I don't think having both of these examples is necessary; one or the other
    should suffice.

    + the other hand if the value of $inputfile was received from an external
    +source and if for some reason the name given includes a leading grater-than
    +sign then the file will be opened for writing. Certainly not what you wanted.
    +Leaving out the leading less-than sign can create a security hole in your code.

    s/grater-than/greater-than/

    To be precise, if the name includes a leading greater-than, a *different*
    file will be opened for writing, corresponding to the given file-name
    without the leading greater-than.

    -There is also a 3-argument version of C<open>, which lets you put the
    -special redirection characters into their own argument:
    +In addition for backward compability with Perl before 5.6.0, one can
    +use bare words as filehandles:
    - open( INF, ">", $datafile ) || die "Can't create $datafile: $!";
    + open( INF, ">$datafile" ) || die "Can't create $datafile: $!";
    +
    +This is not a recommended practice any more as it has several drawbacks
    +such as being INF being global to the whole application and being
    +very hard to pass as argument to a function.

    s/such as being INF being global/such as INF being global/
    s/as argument/as an argument/

    Ronald
  • No.4 | | 821 bytes | |

    Fri, Jul 14, 2006 at 01:04:35PM +0200, H.Merijn Brand wrote:
    Fri, 14 Jul 2006 13:27:32 +0300, "Gabor Szabo" <szabgab (AT) gmail (DOT) comwrote:

    +Reading a file line by line:
    +
    + open my $fh, "<", "data.txt" or die "Could not open data.txt: $!";
    + while (my $line = <$fh>) {

    Is there a good reason you insist on using this?
    And *if* you are using this, do it correct:

    while (defined (my $line = <$fh>)) {

    The explicit defined is no longer necessary; it is implicit even when
    assigning to a variable.

    % perl -M=Deparse -e 'while(<>) {}'
    while (defined($_ = <ARGV>)) {
    ();
    }

    % perl -M=Deparse -e 'while($foo = <>) {}'
    while (defined($foo = <ARGV>)) {
    ();
    }

    Ronald
  • No.5 | | 1433 bytes | |

    7/14/06, Joshua ben Jore <twists (AT) gmail (DOT) comwrote:
    7/14/06, H.Merijn Brand <h.m.brand (AT) xs4all (DOT) nlwrote:
    Fri, 14 Jul 2006 13:27:32 +0300, "Gabor Szabo" <szabgab (AT) gmail (DOT) comwrote:
    You are making up examples here for the inpatient,
    why not just use what we all use

    open my $fh, "<", "data.txt" or die "Could not open data.txt: $!";
    while (<$fh>) {

    I did rather like the assignment to $line. You should remember that $_
    isn't localized and while(<$fh>) will overwrite the $_ for any
    functions that are also running.

    You know I wonder about that. Its something that i think has bitten me
    like once or twice in all my time doing perl, and even then it was
    when i was doing something stupid.

    IM this is one of those over-mentioned traps that really dont bite very often.

    And the

    while ($line=<$fh>) {}

    version might be ok in blead (because the defined is autoadded) buts
    its far from ok in earlier versions, and as it is I think people omit
    the defined a lot just because its a subtle point.

    It seems to me that people will find they get bitten by

    while ($line=<$fh>) { }

    a lot more often than they get bitten by

    while (<$fh>) { }

    so the docs should explain the issue in detail, and then use the
    latter exclusively everywhere else.

    Yves
  • No.6 | | 560 bytes | |

    7/14/06, H.Merijn Brand <h.m.brand (AT) xs4all (DOT) nlwrote:
    Fri, 14 Jul 2006 13:27:32 +0300, "Gabor Szabo" <szabgab (AT) gmail (DOT) comwrote:
    You are making up examples here for the inpatient,
    why not just use what we all use

    open my $fh, "<", "data.txt" or die "Could not open data.txt: $!";
    while (<$fh>) {

    I did rather like the assignment to $line. You should remember that $_
    isn't localized and while(<$fh>) will overwrite the $_ for any
    functions that are also running.

    Josh
  • No.7 | | 1952 bytes | |

    7/14/06, Tom Christiansen <tchrist (AT) perl (DOT) comwrote:
    7/14/06, Joshua ben Jore <twists (AT) gmail (DOT) comwrote:
    >7/14/06, H.Merijn Brand <h.m.brand (AT) xs4all (DOT) nlwrote:

    Fri, 14 Jul 2006 13:27:32 +0300, "Gabor Szabo" <szabgab (AT) gmail (DOT) comwrote:

    I'm going to work off the understanding that that paragraph
    meant to read:
    >
    >+version might be ok in blead (because the defined is autoadded)
    >+but it's far from ok in earlier versions, and as it is, I think
    >+people omit the defined a lot just because it's a subtle point.


    Yes, that was my intended meaning.

    If that's what you'd indended to write, then you're quite right. It is a
    subtle point, and that's why Perl does it for you. Anything that must
    always be included for correctness but which could be neglected and so lead
    to incorrect code should by all means be handled by the supporting language
    environment (library, runtime, etc), for it's too important a matter to be
    swept under the rug of the forgetful programmer.

    You're again right in that prior to a particular point in Perl's
    storied past, no defined() was added, but that after that point, it
    was. In Version 5.004, released on May 15, 1997, Perl did not add the
    defined(), while by the time 5.005 rolled around on July 22, 1998, it
    did. This is obvious from comparing newWHILEP() in op.c between those
    two major versions.

    Actually I didnt realize this. Thanks for clarifying it in such a
    memorable manner. I doubt it shall slip my mind again.

    []
    Bitten? Bitten by what, precisely? I can't see how this dog
    even barks, let alone bites, so why the call for a BEWARE F DG
    placard prominently placed?

    Pray enlighten me.

    Nope. Can't. I was wrong.

    Yves
  • No.8 | | 1245 bytes | |

    Fri, 14 Jul 2006 11:46:33 -0600, Tom Christiansen <tchrist (AT) perl (DOT) comwrote:

    You are making up examples here for the inpatient,
    why not just use what we all use

    open my $fh, "<", "data.txt" or die "Could not open data.txt: $!";
    while (<$fh>) {

    Please; that's hardly what "we all use", unless you should be purporting to
    employ some hypothetical form of the 1st person plural that excludes the
    2nd person, a distinction that while indeed seen in certain tongues is not
    one historically recognized by the English language. Since I for one
    many others must exist don't recognize the existence of such nor
    the truth of your statement, this means your accuracy is more than suspect
    and so requires substantial revision for correctness' sorry sake.

    Blah blah blah again.

    Now in normal English please.
    What do you use then?
    And why do you refuse to go with the flow? Perl moves one, new syntax comes.
    Recent discussions made clear that there is a consensus that 3-arg open is
    (much) better than 2-arg open. If not so, please explain (in understandable
    English) why not. If you agree, why not promote it in the docs, and use it in
    examples.
  • No.9 | | 1404 bytes | |

    7/14/06, H.Merijn Brand <h.m.brand (AT) xs4all (DOT) nlwrote:
    +Reading a file line by line:
    +
    + open my $fh, "<", "data.txt" or die "Could not open data.txt: $!";
    + while (my $line = <$fh>) {

    Is there a good reason you insist on using this?

    Which part are you objecting to? 3-arg open? my $line = <$fh>? The
    fact that its an example of reading from a file?

    You are making up examples here for the inpatient,
    why not just use what we all use

    open my $fh, "<", "data.txt" or die "Could not open data.txt: $!";
    while (<$fh>) {
    chomp; # strip optional trailing $/
    # more processing on $_
    }

    This is perlopentut, not perlimplicittut. We're teaching about using
    open() here, not micro-optimizing your keystrokes. This is also a
    document for newbies. Things should be visible and unambiguous. $_
    is invisible and just adds another point of confusion in what is
    supposed to be a very simple, straightforward explaination of open()
    to users who may not even yet know about $_.

    The "impatient" part is for folks who don't want to read the entire
    document, not for folks who don't want to type out $line.

    PS I'm with what Tom said, in much fewer words. We "all" don't do
    that. I avoid $_. In anything but the simplest loop it just all ends
    in tears.

Re: perlopentut.pod start recommenting $fh instead of FH


max 4000 letters.
Your nickname that display:
In order to stop the spam: 5 + 4 =
QUESTION ON "Perl"

EMSDN.COM