2013-07-03 3 views
5

Dokumentation scheint spärlich in Bezug auf when Aussagen außerhalb given Blöcke. Es wird gesagt, dass die when verwendet werden kann, wenn ein "Thema" festgelegt wurde, aber wann genau ist ein Thema als festgelegt? Betrachten Sie diese Fälle:Unter welchen Bedingungen kann man in Perl 5 eine 'when'-Anweisung verwenden?

for (@arr) { 
    when { } 
} 

scheint dies ist die Standardeinstellung, Grund Fall aber ich konnte nicht einmal diese Arbeit auf meinem Perl 5.14.2 bekommen - $ perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print 'boom'} }' druckt nichts. Was mache ich falsch? Es stellte sich heraus, dass dies nur ein weiteres Bash-Zitat war.

for my $elem (@arr) { 
    when { } 
} 

Würde das funktionieren? Wird $ elem automatisch zum Thema für when werden?

for (@arr) { 
    $_ = some_expression($_); 
    when { } 
} 

Würde das funktionieren? Kann das Thema innerhalb der Schleife gesetzt werden?

Gibt es auch einen Unterschied, wenn jedes der obigen Codesegmente foreach anstelle von for verwendet?

Grundsätzlich bin ich sehr unklar zu dem Thema Themen, also bitte erleuchte mich.

Antwort

7

Es ist ein Shell-Befehl Konstruktionsfehler.

perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print 'boom'} }' 

sollte

perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print '\''boom'\''} }' 

wir doppelte Anführungszeichen wechseln

perl -Mfeature=switch -le'foreach (qw(a b c)) { when (/a/) {print "boom"} }' 

zu vereinfachen und wir können weiter vereinfachen

perl -E'for (qw(a b c)) { when (/a/) { say "boom" } }' 

Keywords for und foreach sind ein und dasselbe für Perl.

Beachten Sie, dass 5,18 markiert given und when als experimentell. Es wird nicht weggehen, aber es wird sich ändern. Ich erkläre, was passiert here.


Nein, when nicht $elem verwendet; es verwendet immer $_.


Ja, können Sie $_ innerhalb von for oder given wenn Sie dies wünschen ändern. Beachten Sie, dass foreach Loops ihr Thema auf das besuchte Element umleiten, sodass das Ändern des einen Elements das andere Element ändert.

my @x = qw(abc def); 
for (@x) { $_ = uc($_); } 
say @x; # ABCDEF 
+0

Ich bin immer falsch mit den Zitaten, danke. Danke für den Link zu Ihrer anderen Antwort, dass und die Links von dort geholfen, den Status besser zu verstehen. Ich habe einen seltsamen Fall mit diesem: 'perl -E '@arr = qw (a b c); foreach $ x (@arr) {$ _ = $ x; $ _ ++; when (/ b /) {print $ x}} '' Es druckt wie erwartet, aber dann scheint mit dem Fehler zu sterben" Kann nicht wenn() außerhalb eines topicizer bei -e Zeile 1 ". Der gleiche Code läuft ohne Fehler (aber nichts drucken), wenn ich die beiden Zeilen mit $ _ entferne. Kannst du erklären, was hier vor sich geht? – sundar

+0

@sundar, Das Problem ist nicht die Wahl der Zitate. Das Problem ist, dass Sie ihnen nicht richtig entkommen konnten. Siehe Aktualisierung. – ikegami

+0

diese Syntax für die Flucht 'ist neu und nützlich für mich, danke. in Bezug auf die Topicalisierung, deshalb habe ich erwähnt, dass "der gleiche Code ohne Fehler ausgeführt wird, wenn ich die zwei Zeilen mit $ _ entfernen". Es scheint, dass jede for/foreach-Schleife als Aktualisierer behandelt wird, selbst für ETWAS (...), aber das Zuweisen zu $ ​​_ innerhalb der Schleife vermasselt das irgendwie. – sundar

2

Ikegami entdeckte Ihr tatsächliches Problem. Bezüglich der anderen Fragen:

Die zwei Topizersind for/foreach und given. Andere Konstrukte, die $_ (die Themavariable) setzen, werden nicht als Aktualisierer betrachtet (z.map oder grep).

Wenn Sie eine foreach-Schleife mit einer expliziten Schleifenvariable ausführen, wird die Schleife nicht als ein Aktualisierungsfaktor betrachtet. Daher

for my $x (1..3) { 
    local $_ = $x; 
    say when 2; 
} 

wird für die erste Iteration arbeiten, aber dann die (nicht „wenn“ außerhalb eines topicalizer), sobald die when wird verlassen.

Die given unterscheidet sich darin, dass sie $_ nicht lokalisiert, aber eine lexikalische $_ gibt. Das heißt, given (@a) { foo; } ist ähnlich wie { my $_ = \@a; foo; } (ich denke, das könnte behoben sein).

Verwandte Themen