in reply to First attempt at bringing in file for input/output

I have some issues with your indenting.
It is not allowed to optionally create a variable in an if statement.
I would strongly advise to "use strict;"
I suggest something like the following...
#!/usr/bin/perl use warnings; use strict; use File::Basename; die "usage: $0 in_file\n" if @ARGV !=1; my $in_file = shift @ARGV; my($filename, $dir, $suffix) = fileparse($in_file); my $out_file = "$dir/$filename.out"; #change the suffix open my $FH_infile, '<', "$in_file" or die "Can't open $in_file"; open my $FH_outfile, '>', "$out_file" or die "Can't open $out_file";
I didn't run this code, but I think it is a good general idea...

Replies are listed 'Best First'.
Re^2: First attempt at bringing in file for input/output
by talexb (Chancellor) on Oct 21, 2018 at 16:44 UTC

    Although operator precedence will do the right thing in your code ..

    open my $FH_infile, '<', "$in_file" or die "Can't open $in_file"; open my $FH_outfile, '>', "$out_file" or die "Can't open $out_file";
    I prefer the more explicit
    open ( my $FH_infile, '<', "$in_file" ) or die "Can't open $in_file"; open ( my $FH_outfile, '>', "$out_file" ) or die "Can't open $out_file";
    In addition, I do like to give myself as much information as possible by adding $! to error messages:
    open ( my $FH_infile, '<', "$in_file" ) or die "Can't open $in_file: $!"; open ( my $FH_outfile, '>', "$out_file" ) or die "Can't open $out_file: $!";
    Also, I wasn't aware of File::Basename .. that's pretty handy.

    Alex / talexb / Toronto

    Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

      Don't know why I didn't have $! in the die message. Good catch..including that is a good idea and I do it except when I make a mistake like above!

      While we are talking about die messages, another option that I sometimes use is to suppress the Perl module name and source code line number from the error message. That is done by simply adding a \n to the message, e.g.  die "Can't open $out_file: $!\n"; This choice has to do with who I'm writing the code for. For other programmers, sys admin types, I leave everything in there. Sometimes I write pre-complied .exe's for very inexperienced computer users and in that case, I've found that the extraneous information doesn't help them because they don't understand it and they don't have the source code anyway. I rarely do this, but rare doesn't mean "never".

Re^2: First attempt at bringing in file for input/output
by haukex (Archbishop) on Oct 22, 2018 at 08:34 UTC
    It is not allowed to optionally create a variable in an if statement.

    You're probably referring to this piece of documentation (discussed in e.g. Variable Scope):

    NOTE: The behaviour of a my, state, or our modified with a statement modifier conditional or loop construct (for example, my $x if ...) is undefined. The value of the my variable may be undef, any previously assigned value, or possibly anything else. Don't rely on it. Future versions of perl might do something different from the version of perl you try it out on. Here be dragons.

    However, if you are referring to syntax like if (open my $fh, '<', 'file.txt'), this is perfectly legal; from Private Variables via my():

    if ((my $answer = <STDIN>) =~ /^yes$/i) { user_agrees(); } elsif ($answer =~ /^no$/i) { user_disagrees(); } else { chomp $answer; die "'$answer' is neither 'yes' nor 'no'"; }
    the scope of $answer extends from its declaration through the rest of that conditional, including any elsif and else clauses, but not beyond it.

    One very common case of this kind of scoping being while (my $line = <>).

      I liked your post++

      To further clarify this and another thread having to do with while loop and $line=<filehande>:

      #!usr/bin/perl use strict; use warnings; while (my $line =<DATA> and $line !~ /^\s*$/) { print "do somehing with non blank line\n"; } __END__ Value of <HANDLE> construct can be "0"; test with defined() at C:\User +s\mmtho\Documents\PerlProjects\Monks\test_myVar_inwhile.pl line 5. Global symbol "$line" requires explicit package name (did you forget t +o declare "my $line"?) at C:\Users\mmtho\Documents\PerlProjects\Monks +\test_myVar_inwhile.pl line 5. Execution of C:\Users\mmtho\Documents\PerlProjects\Monks\test_myVar_in +while.pl aborted due to compilation errors.
      To fix the first error message,...
      #!usr/bin/perl use strict; use warnings; while (defined (my $line =<DATA>) and $line !~ /^\s*$/) { print "do somehing with non blank line\n"; } __END__ Global symbol "$line" requires explicit package name (did you forget t +o declare "my $line"?) at C:\Users\mmtho\Documents\PerlProjects\Monks +\test_myVar_inwhile_ver2.pl line 6. Execution of C:\Users\mmtho\Documents\PerlProjects\Monks\test_myVar_in +while_ver2.pl aborted due to compilation errors.
      Back up and fix just this error message...
      #!usr/bin/perl use strict; use warnings; my $line; while ($line =<DATA> and $line !~ /^\s*$/) { print "do somehing with non blank line\n"; } __END__ Value of <HANDLE> construct can be "0"; test with defined() at C:\User +s\mmtho\Documents\PerlProjects\Monks\test_myVar_inwhile_ver2.pl line +7. do somehing with non blank line do somehing with non blank line
      To make this work completely:
      #!usr/bin/perl use strict; use warnings; my $line; while (defined($line =<DATA>) and $line !~ /^\s*$/) { print "do somehing with non blank line\n"; } __END__ do somehing with non blank line do somehing with non blank line do somehing with non blank line do somehing with non blank line
        To make this work completely

        In such loops I prefer to limit the scope of $line but this might not concern you.

        #!usr/bin/perl use strict; use warnings; while (my $line = <DATA>) { last unless $line =~ /\S/; print "Read: $line"; } __DATA__ do a thing with non blank line do a thing with non blank line last one no action on this line nor this
Re^2: First attempt at bringing in file for input/output
by AnomalousMonk (Archbishop) on Oct 22, 2018 at 02:02 UTC
    It is not allowed to optionally create a variable in an if statement.

    I cannot see where this is attempted; can you point this out? (I assume you're referring to the OPed code, but I can't see it anywhere in the thread.) (Update: As an aside, note that conditional creation of a variable is "allowed" in the sense that it is not a syntactic error, but it's not a good idea for reasons discussed here and documented here.)

    open my $FH_infile, '<', "$in_file" or die "Can't open $in_file";

    And just to satisfy my idle curiosity, can you say why you use the  "$in_file" idiom (stringizing a string)? (I notice talexb also uses the idiom here.)


    Give a man a fish:  <%-{-{-{-<

      As an aside, note that conditional creation of a variable is "allowed" in the sense that it is not a syntactic error

      Not really a syntax error, no, but:

      $ perl -wMstrict -Mdiagnostics -e 'my $x if 0' Deprecated use of my() in false conditional. This will be a fatal erro +r in Perl 5.30 at -e line 1 (#1) (D deprecated) You used a declaration similar to my $x if 0. Ther +e has been a long-standing bug in Perl that causes a lexical variabl +e not to be cleared at scope exit when its declaration includes a fa +lse conditional. Some people have exploited this bug to achieve a kin +d of static variable. Since we intend to fix this bug, we don't want p +eople relying on this behavior. You can achieve a similar static effect + by declaring the variable in a separate block outside the function, e +g sub f { my $x if 0; return $x++ } becomes { my $x; sub f { return $x++ } } Beginning with perl 5.10.0, you can also use state variables to ha +ve lexicals that are initialized only once (see feature): sub f { state $x; return $x++ } This use of my() in a false conditional has been deprecated since Perl 5.10, and it will become a fatal error in Perl 5.30.

      See also #133543.