2009-09-25 5 views
44

Mam dwa pytania dotyczące Perl open funkcję:Dlaczego trzyargumentowe połączenia otwarte z autowybranymi uchwytami plików to najlepsza praktyka Perla?

1) wydaje mi się, ze Perl Dobrych Praktyk że wersja 3-argument open jest lepszy niż wersja dwóch argumentów, np

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

vs.

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

Dlaczego tak jest? Próbowałem powiedzieć komuś, żeby wczoraj skorzystał z wersji 3-argumentowej, ale nie mógł tego zrobić z niczym.

2) Wydaje mi się również pamiętać, że autovivified filewrady są faworyzowane przez barewrace filehandles (nazwały coś innego)? A także nie pamiętam, dlaczego, np.

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

vs.

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

Czy to strict rzecz? Pamiętam, że mogłem używać OUT z, ale nie pamiętam.

+0

dupe: http://stackoverflow.com/questions/318789/whats-the-best-way-to-open-and-read-a-flub-in-perl – Ether

+1

To dlatego, że Perl :: Critic radzi to:) –

+3

To nie jest dupe, to pytanie, dlaczego jest to najlepszy sposób na zrobienie tego. –

Odpowiedz

62
  • Korzystanie Typeglob dla uchwytów plików (jak OUT) nie jest dobrym pomysłem , ponieważ są one globalne w całym programie - musisz mieć pewność, że żadna inna procedura, w tym te w modułach, nie używa tej samej nazwy (w tym w przyszłości).
  • Użycie dwuargumentowej formy otwartej naraża aplikację na niewłaściwe zachowanie spowodowane przez zmienne zawierające znaki specjalne, na przykład my $f; open $f, ">$some_filename"; jest narażone na błąd, w którym $some_filename zawierający wiodący > zmieni zachowanie programu.

Użycie trzyargumentowej postaci pozwala tego uniknąć, oddzielając tryb i nazwę pliku od oddzielnych argumentów, w których nie mogą się wtrącać.

Ponadto, przy użyciu partie-of-argumentów tworząc z rur jest bardzo dobrym pomysłem:

open $pipe, '|-', 'sendmail', '[email protected]'; 

Czy lepiej niż robi to wszystko za jednym ciągiem - unika możliwego zastrzyku powłoki itp

+1

Dzięki MarkR. To był DOKŁADNIE zestaw odpowiedzi, których szukałem. Cieszę się, że mam uzasadniony powód, dla którego zrobiłem to w ten sposób przez ostatnie kilka lat. – Morinar

+3

Uwagi na temat kompatybilności: 3-arg open i 'open my $ fh, ...' zaczynają się od 5.6.0. 'otwórz moje $ fh, '| -', LIST' (lista potokowa otwarta) zaczyna się od 5.8.0. – hobbs

+1

Nie ma powodu, aby używać brzydkiej formy otwierania potoków na literałach znanych treści, takich jak ta sugerowana. Ponadto przerwiesz obsługę powłoki złożonych potoków. Zły zły zły. – tchrist

14

Walka nr 2:

OUT jest globalnym filehandle i stosując to naraża się podstępnych błędów tak:

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

Ahh, to bardzo solidny argument. – Morinar

12

Jednym z aspektów, o którym należy pamiętać, jest to, że forma dwuargumentowa jest zepsuta. Rozważmy plik o nazwie "abc" (to jest nazwa pliku z wiodącym pustym miejscem). Nie można otworzyć pliku:

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

Miejsce zostanie upuszczone, a plik nie będzie już można znaleźć. Taki scenariusz jest wysoce nieprawdopodobny, ale zdecydowanie stanowi problem.Formularz trzy-arg jest odporny na to:

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

This thread z perlmonks jest tak dobra, jak każda dyskusja na ten temat. Pamiętajmy tylko, że w 2001 r. Forma trzech argów była nadal uważana za nową, a zatem nie nadaje się do przenośnego kodu, ponieważ programy Perla umrą z błędem składni, jeśli uruchomimy go na interprerze 5.005. To już nie jest tak: perl 5.005 jest poza przestarzałym, jest przestarzały.

+16

Nie, dwuargumentowa forma otwartej lub jednokomórkowej postaci w tym przypadku jest * nie * zepsuta. Działa tak, jak zostało zaprojektowane, udokumentowane i reklamowane. Po prostu może być tak, że * magia otwarta * nie jest tym, czego potrzebujesz. Kolejną wtyczką dla trzech argumentów open jest to, że środkowy argument może - i często powinien - zawierać kodowanie strumienia. – tchrist

Powiązane problemy