Why is three-argument open calls with autovivified filehandles a Perl best practice?

后端 未结 3 719
-上瘾入骨i
-上瘾入骨i 2020-11-22 12:32

I\'ve got two questions about the Perl open function:

1) I seem to remember from Perl Best Practices that the 3-argument version of open<

相关标签:
3条回答
  • 2020-11-22 12:46

    Tackling #2:

    OUT is a global filehandle and using it exposes you to insidious bugs like this:

    sub doSomething {
      my ($input) = @_;
      # let's compare $input to something we read from another file
      open(F, "<", $anotherFile);
      @F = <F>; 
      close F;
      &do_some_comparison($input, @F);
    }
    
    open(F, "<", $myfile);
    while (<F>) {
        &doSomething($_);   # do'h -- just closed the F filehandle
    }
    close F;
    
    0 讨论(0)
  • 2020-11-22 12:46

    One aspect to keep in mind is that the two-arg form is broken. Consider a file named ' abc' (that is, a file name with a leading blank). You cannot open the file:

    open my $foo, ' abc' or die $!;
    open my $foo, '< abc' or die $!;
    open my $foo, '<  abc' or die $!;
    # nothing works
    

    The space gets dropped and so the file can no longer be found. Such a scenario is highly improbable, but definitely a problem. The three-arg form is immune to this:

    open my $foo, '<', ' abc' or die $!;
    # works
    

    This thread from perlmonks is as good a discussion as any of the issue. Just bear in mind that in 2001, the three-arg form was still considered new, and thus not suitable for portable code, since Perl programs would die with a syntax error if run on a 5.005 interpreter. This is no longer the case: perl 5.005 is beyond deprecated, it is obsolete.

    0 讨论(0)
  • 2020-11-22 13:01
    • Using typeglobs for filehandles (like OUT) is not a good idea, as they are global across your entire program - you need to be sure that no other routine including those in modules are using the same name (including in the future).
    • Using the two-argument form of open exposes your application to mis-behaviour caused by variables containing special characters, for example my $f; open $f, ">$some_filename"; is exposed to the bug where $some_filename containing a leading > will change the program's behaviour.

    Using the three-argument form avoids this by separating the mode and filename into separate arguments where they can't interfere.

    Moreover, using the lots-of-arguments form with pipes is a very good idea:

    open $pipe, '|-', 'sendmail', 'fred@somewhere.fake';
    

    Is better than doing it all as a single string – it avoids possible shell injection etc.

    0 讨论(0)
提交回复
热议问题