2010-05-22 18 views
7

In Perl werden Klammern zum Überschreiben der Priorität (wie in den meisten Programmiersprachen) sowie zum Erstellen von Listen verwendet. Wie kann ich feststellen, ob ein bestimmtes Paar von Parens als Gruppierungskonstrukt oder als Ein-Element-Liste behandelt wird?Wie kann ich feststellen, ob eine Gruppe von Parens im Perl-Code als Gruppierung oder als Liste fungiert?

Zum Beispiel bin ich mir ziemlich sicher, dass dies eine skalare und keine Ein-Element-Liste ist: (1 + 1)
Aber was ist mit komplexeren Ausdrücken? Gibt es eine einfache Möglichkeit zu erzählen?

+0

Ich mache mir Sorgen, dass ich versehentlich eine Ein-Element-Liste mit einem Ergebnis statt dem Ergebnis selbst einem Skalar zuweisen würde. Aber wenn ich die Antworten richtig lese, ist das eigentlich unmöglich, außer ich mache etwas wie $ x = @ {[1 + 1]}; Es scheint, dass das Zuweisen einer Liste zu einem Skalar anders ist als das Zuweisen eines Arrays zu einem Skalar. Was passiert, wenn Sie einem Skalar eine Liste zuweisen, die ein Array enthält? '$ x = (@list);' –

+0

In einer Zuweisung bestimmt die linke Seite den Kontext, in dem die rechte Seite ausgewertet wird. Wenn Sie also ein Array einer skalaren Variablen zuweisen, wird das Array im skalaren Kontext ausgewertet. Ein Array, das im skalaren Kontext ausgewertet wird, gibt die Anzahl der Elemente im Array zurück. Beide Beispiele in Ihrem Kommentar fallen unter diese Kategorie. Beachten Sie auch, dass es sich hier um die Bewertung eines Arrays im skalaren Kontext handelt. Wir sprechen nicht über eine Liste im skalaren Kontext, da es keine Listen im skalaren Kontext gibt. – FMc

+0

Ich denke, ich habe immer daran gedacht, dass Listen und Arrays grundsätzlich äquivalent und austauschbar sind, aber das sind sie nicht. –

Antwort

16

Drei wichtige Grundsätze sind nützlich, hier:

Kontext ist König. Die Auswertung Ihres Beispiels (1 + 1) hängt vom Kontext ab.

$x = (1 + 1); # Scalar context. $x will equal 2. Parentheses do nothing here. 
@y = (1 + 1); # List context. @y will contain one element: (2). 
       # Parens do nothing (see below), aside from following 
       # syntax conventions. 

In einem skalaren Kontext gibt es nicht so etwas wie eine Liste. Versuchen Sie, das zu sehen, was erscheint, um eine Liste zu einer Skalarvariablen zu sein. Die Art und Weise, darüber nachzudenken, besteht darin, sich auf das Verhalten des Komma-Operators zu konzentrieren: Im skalaren Kontext wertet es sein linkes Argument aus, wirft diesen Wert weg, wertet dann sein rechtes Argument aus und gibt diesen Wert zurück. Im Listenkontext fügt der Kommaoperator beide Argumente in die Liste ein.

@arr = (12, 34, 56); # Right side returns a list. 

$x = (12, 34, 56); # Right side returns 56. Also, we get warnings 
         # about 12 and 34 being used in void context. 

$x = (@arr, 7);  # Right side returns 7. And we get a warning 
         # about using an array in a void context. 

Klammerung nicht schaffen Listen. Der Komma-Operator erstellt die Liste (vorausgesetzt, wir befinden uns im Listenkontext). Wenn Sie Listen in Perl-Code eingeben, werden die Klammern aus Gründen der Priorität benötigt - nicht aus Gründen der Listenerstellung. Ein paar Beispiele:

  • Die Klammern haben keine Wirkung: wir ein Array in skalare Kontext evaluieren, so dass die rechte Seite gibt die Array-Größe.

    $x = (@arr); 
    
  • Klammern sind nicht erforderlich, um eine Liste mit einem Element zu erstellen.

    @arr = 33;   # Works fine, with @arr equal to (33). 
    
  • Aber Klammern sind mit mehreren Elementen erforderlich - aus Vorranggründen.

    @arr = 12, 34, 56; # @arr equals (12). And we get warnings about using 
            # 34 and 56 in void context. 
    
8
  1. Kontext.
  2. Klammern haben nicht die Rolle, die Sie beim Erstellen einer Liste haben.

Beispiele:

$x = 1 + 1; # $x is 2. 
$x = (1 + 1); # $x is 2. 
@x = 1 + 1; # @x is (2). 
@x = (1 + 1); # @x is (2). 

$x = (1 + 1, 1 + 2); # $x is 3. 
@x = (1 + 1, 1 + 2); # @x is (2, 3). 

Grob gesagt, der Komma-Operator in Listenkontext Elemente einer Liste trennt; Im skalaren Kontext ist der Kommaoperator das C "serielle Komma", das seine linke und rechte Seite auswertet und den Wert der rechten Seite zurückgibt. Im skalaren Kontext gruppieren die Ausdrücke in Klammern die Reihenfolge der Operationen und im Listenkontext bedeuten Klammern genau das Gleiche.Der Grund, warum sie bei der Zuordnung zu Arrays relevant ist, ist dies:

# Comma has precedence below assignment. 
# @a is assigned (1), 2 and 3 are discarded. 
@a = 1, 2, 3; 

# @a is (1, 2, 3). 
@a = (1, 2, 3); 

Was Ihre Frage „ist es ein Skalar oder eine Ein-Element-Liste“, es ist einfach nicht eine sinnvolle Frage eines Ausdrucks in Isolation fragen aufgrund des Kontextes. Im Listenkontext ist alles eine Liste; im skalaren Kontext ist nichts.

Empfohlener Wert: perlop, perldata, Programmierung Perl.

+0

Ich mag Deparse, um den Komma-Operator zu zeigen: perl -MO = Deparse -le 'my @s = 1,3,4; print "@s" ' BEGIN {$/= "\ n"; $ \ = "\ n"; } my (@s) = 1, '???', '???'; print "@s"; -e Syntax OK –