45 votes

Pourquoi les appels ouverts à trois arguments avec fichiers auto-administrés constituent-ils une bonne pratique Perl?

J'ai deux questions à propos du Perl open fonction de:

1) il me semble me rappeler de Perl Best Practices que le 3-l'argument de la version de open est mieux que les deux argument de la version, par exemple

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

vs

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

Pourquoi est-ce? J'ai essayé de dire à quelqu'un, l'utilisation de la 3-l'argument de la version de l'autre jour, mais n'arrivais pas à le sauvegarder avec quoi que ce soit.

2) j'ai aussi semble me rappeler autovivified descripteurs être favorisée par rapport à mot nu descripteurs (ils appelés quelque chose de différent)? Et aussi ne pouvait pas se rappeler pourquoi, par exemple

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

vs

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

Est-il un strict chose? Il me semble me rappeler d'être en mesure d'utiliser OUT avec strict mais je ne me souviens pas.

64voto

MarkR Points 37178
  • À l'aide de typeglobs de descripteurs (comme OUT) n'est pas une bonne idée, car ils sont au niveau mondial sur l'ensemble de votre programme, vous devez être sûr qu'aucun autre de routine, y compris ceux dans les modules sont en utilisant le même nom (y compris dans le futur).
  • En utilisant les deux argument forme d'ouvrir expose votre application à une erreur de comportement causés par des variables contenant des caractères spéciaux, par exemple my $f; open $f, ">$some_filename"; est exposé à l'erreur où l' $some_filename contenant l'un des leaders > va changer le programme du comportement.

À l'aide des trois-argument forme évite en séparant le mode et le nom de fichier pour séparer les arguments d'où ils ne peuvent pas interférer.

En outre, en utilisant beaucoup les arguments de forme avec des tuyaux est une très bonne idée:

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

Est mieux que de le faire tous comme une seule chaîne, il évite au possible injection de shell etc.

16voto

mob Points 61524

Tackling # 2:

OUT est un descriptif de fichier global et son utilisation vous expose à des bugs insidieux comme celui-ci:

 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;
 

13voto

dland Points 2033

Un aspect à garder à l'esprit est que les deux-arg forme est cassé. Envisager un fichier nommé " abc " (c'est un nom de fichier précédé d'un espace). Vous ne pouvez pas ouvrir le fichier:

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

L'espace est perdu et donc le fichier ne peut plus être trouvé. Un tel scénario est hautement improbable, mais certainement un problème. Les trois-arg forme est à l'abri de cette:

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

Ce fil de perlmonks est aussi bon une discussion tout de la question. Il suffit de garder à l'esprit que, en 2001, les trois-arg forme était encore considéré comme nouveau, et n'est donc pas adapté pour un code portable, depuis les programmes Perl mourrait avec une erreur de syntaxe si vous exécutez sur un 5.005 interprète. Ce n'est plus le cas: perl 5.005 est au-delà obsolète, il est obsolète.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X