2013-06-29 20 views
8

documentation for the open function przedstawia składnię open() jak:Dlaczego w dokumentacji Perl open() są używane dwa różne style UCHWYTU pliku?

  • otwartego uchwytu pliku wyraż
  • otwarty UCHWYTPLIKU, tryb EXPR
  • otwarty UCHWYTPLIKU, tryb EXPR, lista
  • otwarty UCHWYTPLIKU MODE mającej
  • open UCHWYTPLIKU

dół w przykładach mają miejsca gdzie normalny $ -prefixed zmienna służy do uchwytu pliku:

open(my $fh, "<", "input.txt") 

a także przykładów, gdy stosuje się gołe słowo:

open(FOO, "|tr '[a-z]' '[A-Z]'"); 

Jedno pytanie jest jaka jest nazwa każdego stylu, jak w " Używam _ _ dla uchwytu pliku "w każdym przypadku? Drugim jest, , dlaczego zaczęli używać gołe słowa dla open() w dokumentacji? Wygląda na to, że późniejsze zastosowania nie obejmują zwykłego pliku o nazwie open(). Czy w tych przypadkach forma niedopasowana $ jest niedopuszczalna?

+1

wielkie pytanie, zawsze byłem zdenerwowany przez tę składnię – qwwqwwq

+0

Kinda denerwujące robić 'open (STDOUT," less ")' w jakikolwiek inny sposób. – tchrist

Odpowiedz

20

Forma bareword jest zasadniczo historycznym dziedzictwem ze względu na kompatybilność wsteczną. Używanie zmiennej leksykalnej jest właściwie zawsze właściwym zadaniem w nowym kodzie.

→ notabene $x jest leksykalne zmienną skalarną, gdzie FOO jest, jak pan powiedział, zwane gołe słowo

Szczegóły/dygresja

Tylko dla kompletności, jak wskazano w @Joe_Z komentarze, leksykalne obiekty filehandle są "względnie nowe", jako część raczej poważnej przeróbki między Perl 5.005 a 5.6 (nawet zyskały całe rzędy wielkości w tym numerze wersji ...).

Jednak technicznie, bareword FOO (lub np. STDIN) jest interpretowany w oddzielnej przestrzeni nazw tylko dla uchwytów plików. Ponieważ nie jest Sigil (jak $ @ % &) dla nazw filehandle, istnieją tylko dwa sposoby odwołujące uchwytu pliku w tej przestrzeni nazw:

  • Można odwołać się do niego w gnieździe pośrednim Celem niektórych funkcji, jak print, który (za kulisami) wywnioskuje, że bareword musi odnosić się do uchwytu pliku, z przyczyn historycznych;
  • Możesz użyć typeglob, jak *FOO, który odnosi się do "wszystkiego w dowolnej przestrzeni nazw, która jest związana z symbolem FOO.

Należy zauważyć, że w niektórych językach, takich jak C lub programu, pojedynczy symbol ma sigile typu, a więc wszystkie symbole mogą być związane tylko w jeden sposób (np nie można mieć zmienną o nazwie printf oraz funkcja o nazwie printf w C ... ogólnie), podczas gdy w Perlu lub (np) Common Lisp, ten sam symbol foo może wiązać się z wieloma różnymi rzeczami; rozróżnienie polega na tym, że Perl w rzeczywistości wymaga użycia sigilów, aby rozróżnić "co to jest foo" w większości kontekstów. $foo, @foo = @foo[ $x .. $y], $foo[ $n ], %foo = @foo{ $k1, $k2 } = $foo{ $k }, &foo i tym podobne.

Korzystając gołe słowa jako uchwytów plików, choć, można stracić kilka możliwości:

znacząco, aby powiązać je lokalnie lub leksykalnie (zamiast globalnie), trzeba wiązać każdy symbolu w każdej przestrzeni nazw, ponieważ nie ma sygnatury. Tak więc, my $foo i my @foo mogą żyć w dwóch różnych scratchpadach (zakresach), gdzie być może jeden przeżyje drugi; ale my *foo zawierałby oba te elementy, a także uchwyt pliku foo (i potencjalnie inne niejasne przypadki narożne, takie jak specyfikatory format, chociaż nie przysięgłbym na to).

Niezmiernie trudno jest przekazać uchwyt pliku w stylu bareword do funkcji i tym podobne.

Zasadniczo, barewords dziedziczą wszystkie wady globalnego zasięgu i nie mają żadnych zalet zmiennych leksykalnych.

perldoc perldata ma ładny dział na Kufle i rękojeści, które prawdopodobnie wyjaśniają te kwestie nieco jaśniej. Nie mam przy sobie mojego egzemplarza, ale wierzę, że Camel również bardziej szczegółowo zajmie się tym tematem.

+5

+1: Używanie uchwytów plików leksykalnych jest "sposobem na zrobienie tego", mimo że jest to Perl, więc TMTOWTDI (istnieje więcej niż jeden sposób, aby to zrobić). –

+1

@ JonathanLeffler zarówno silny punkt, jak i wada. – jordanm

+0

coz Jestem trochę starym skoolem Od czasu do czasu używam uchwytów plików w stylu globalnym w odpowiedziach i niezmiennie dostaję negatywne komentarze na ten temat :) Zgadzam się, że leksykalne filehandle są lepsze, ale to twardy nawyk łamać! – Vorsprung

2

Jak BPRocock powiedział my $x jest korzystne w tych dniach, natomiast FOO jest uważane za przestarzałe, ponieważ FOO jest rodzajem zmiennych globalnych więc może to kolidować z nazw używanych w innym miejscu. Istnieje jeszcze jeden powód, dla którego zachęca się $x: $x zostanie automatycznie zmieniony na koniec zakresu.