Por que as chamadas abertas de três argumentos com filehandles autovivificadas são uma prática recomendada do Perl?

Eu tenho duas perguntas sobre a function open do Perl:

1) Eu pareço lembrar de Perl Best Practices que a versão de 3 argumentos do open é melhor que a versão de dois argumentos, por exemplo

 open(OUT, '>>', $file); 

vs.

 open(OUT, ">>$file"); 

Por que é que? Eu estava tentando dizer a alguém para usar a versão de 3 argumentos no outro dia, mas não conseguia dar suporte a nada.

2) Eu também pareço lembrar que as filehandles autovivificadas estão sendo favorecidas por meio de filehandles bareword (eles chamaram algo diferente)? E também não conseguia lembrar por que, por exemplo

 open(my $out, '>>', $file); 

vs.

 open(OUT, '>>', $file); 

É uma coisa strict ? Eu pareço lembrar de ser capaz de usar OUT com strict mas não me lembro.

  • Usar typeglobs para filehandles (como OUT ) não é uma boa ideia, pois eles são globais em todo o seu programa – você precisa ter certeza de que nenhuma outra rotina incluindo aqueles em módulos está usando o mesmo nome (inclusive no futuro).
  • Usar o formulário de dois argumentos do open expõe seu aplicativo a um comportamento incorreto causado por variables ​​contendo caracteres especiais, por exemplo, my $f; open $f, ">$some_filename"; my $f; open $f, ">$some_filename"; é exposto ao bug onde $some_filename contendo um leading > mudará o comportamento do programa.

Usar o formulário de três argumentos evita isso separando o modo e o nome de arquivo em argumentos separados, onde eles não podem interferir.

Além disso, usar a forma de lotes de argumentos com pipes é uma boa ideia:

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

É melhor do que fazer tudo como uma única string – evita uma possível injeção de shell, etc.

Enfrentando # 2:

OUT é um filehandle global e usá-lo expõe a insidiosos erros como este:

 sub doSomething { my ($input) = @_; # let's compare $input to something we read from another file open(F, "< ", $anotherFile); @F = ; close F; &do_some_comparison($input, @F); } open(F, "< ", $myfile); while () { &doSomething($_); # do'h -- just closed the F filehandle } close F; 

Um aspecto a ter em mente é que a forma de dois argumentos está quebrada. Considere um arquivo chamado ‘abc’ (isto é, um nome de arquivo com um espaço em branco à esquerda). Você não pode abrir o arquivo:

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

O espaço é descartado e, portanto, o arquivo não pode mais ser encontrado. Tal cenário é altamente improvável, mas definitivamente um problema. A forma de três arg é imune a isso:

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

Esta discussão de perlmonks é tão boa discussão quanto qualquer um dos problemas. Apenas tenha em mente que, em 2001, a forma de três args ainda era considerada nova e, portanto, não adequada para código portátil, já que os programas Perl morreriam com um erro de syntax se fossem executados em um interpretador 5.005. Isso não é mais o caso: o perl 5.005 está além de ser obsoleto, é obsoleto.