2009-10-28 6 views
5

Ich glaube nicht, dass die folgenden funktionieren sollte, aber es funktioniert:Durchläuft der Perl-Diamantoperator nicht-magische Arrays (nicht @ARGV)?

$ perl -e '@a = qw/1222 2 3/; while (<@a>) { print $_ ."\n";}' 
1222 
2 
3 
$ 

Soweit ich weiß, <> Bedienungs Perl shoud auf Dateihandle, Klackse arbeiten und so weiter, mit Ausnahme des wörtlichen <> (anstelle von <FILEHANDLE>), die magisch über @ARGV iteriert.

Weiß jemand, ob es auch so funktionieren soll wie in meinem Test?

+0

Von perlop (1) über <> und @ARGV: So funktioniert es: Beim ersten Mal <> wird ausgewertet, das @ ARGV-Array wird überprüft, und wenn es leer ist, wird $ ARGV [0] gesetzt zu "-", die beim Öffnen gibt Standardeingabe. Das @ ARGV-Array wird dann als eine Liste von Dateinamen verarbeitet. Ich kann etwas Ähnliches mit meinem @a passiert sehen, obwohl es nicht scheint, dass das mit jedem Array passieren sollte (und ich weiß, dass die Foreach oder Map bessere Wege sind, um Arrays zu bearbeiten). Ich möchte immer noch wissen, warum, ohne sich in den Code graben –

Antwort

10

Magie bei der Arbeit

Aus ‚perldoc perlop‘:

Wenn was ist innerhalb der spitzen Klammern ist weder ein Dateihandle noch eine einfache skalare Variable einen Dateikennung Name, Typeglob oder Typeglob Referenz enthält, es als Dateinamen Muster interpretiert werden globbed, und entweder eine Liste von Dateinamen oder der nächste Dateiname in der Liste ist zurückgegeben, abhängig vom Kontext.

Dies ist die Regel, die Sie mit diesem Code auslösen. Hier ist, was passiert:

  1. < @a> ist (syntaktisch, zur Compile-Zeit) bestimmt eine glob Expansion sein
  2. so <> schaltet @a in die Zeichenfolge "1222 2 3" (string Interpolation Array)
  3. glob ("1222 2 3") in Listenkontext zurückkehrt ('1222', '2', '3')
+0

OK, also bin ich gerade aufgestanden, aber ich bekomme einfach nicht # 3. – innaM

+0

Das Verhalten ist: Wenn es in seinem Argument keine Muster-Metazeichen gibt, kümmert sich glob nicht darum, zum Dateisystem zu gehen. Dies kann überraschend sein. Es hilft mir, es in Bezug auf die Shell-Glob-Funktionalität zu denken, die Perls Glob emulieren soll: Wenn du 'cat foo' sagst, ruft die Shell 'cat' mit einem Argument von 'foo' auf, egal ob 'foo' existiert. Wenn Sie 'cat foo. *' Sagen, wird die Shell 'cat' mit variablen Argumenten aufrufen, je nachdem, was (wenn überhaupt) mit dem Muster übereinstimmt. – dlowe

+0

Danke! Jetzt habe ich es verstanden. – innaM

-1

<FH> ist nicht der Name eines Dateihandles, sondern ein Winkeloperator, der eine Zeileneingabeoperation am Handle ausführt. Diese Verwirrung in der Regel manifestiert sich, wenn Menschen versuchen, auf den Winkel Operator drucken“- Programming Perl

Also in Ihrem Fall das Array ein Griff ist, was Sinn macht, und damit der Bediener iteriert es also in Antwort auf Ihre. Frage, ja, ich denke, das ist Standard (aber obskur) Perl. Es ist obskur, weil die Sprache offensichtlicher Möglichkeiten hat, über ein Array zu durchlaufen.

PS Aber danke dafür, das wird großartig für Code Golf-Wettbewerben .

+0

Veröffentlichen Sie keine Links zu nicht autorisierten Kopien von Büchern. –

+0

Whoops, ich habe es nicht einmal bemerkt.Entschuldigung für diesen. –

+1

foreach (@a) ist genauso kurz und einfach wie während (<@a>), so dass es nicht viel Code Golf hilft. –

1

Dies wird Aufruf glob.