2013-07-05 9 views
17

Normalerweise beginnt ein Paket einfach alsGibt es einen Unterschied zwischen "Standard" und Blockpaket-Deklaration?

package Cat; 
... #content 
!0; 

ich gerade entdeckt, dass auch von der Perl-Start 5.14 gibt die „Block“ Syntax ist.

package Cat { 
    ... #content 
} 

Es ist wahrscheinlich das gleiche. Aber nur um sicher zu sein, gibt es irgendwelche Unterschied?

Und über die 1; am Ende der Paketdatei. Der Rückgabewert eines Blocks wird als Wert des letzten ausgewerteten Ausdrucks verwendet. Kann ich also die 1; vor die schließende } setzen? Um require glücklich zu machen, gibt es einen Unterschied zwischen:

package Cat { 
    ... #content 
    1; 
} 

und

package Cat { 
    ... #content 
} 
1; 
+0

Ich schlage nur vor, dass, wenn 'require' auf jeden Fall glücklich ist (kein Unterschied), dann gibt es keinen Unterschied in Bezug auf' require'. Willst du sagen, dass es nicht hilfreich ist, Antworten zu finden, indem du den Code selbst ausprobierst? – doubleDown

+1

@Nemo 'Paket NAME {...}' ist nur syntaktischer Zucker für '{Paket NAME; ...} '; Sie sind genau das Gleiche. Wenn die letzte Anweisung in Ihrer Datei ein Block ist, dann ist die letzte Anweisung im Block der Wert, den 'require' erhalten wird. – amon

+1

Um fair zu sein, hat Ihre Frage nicht erwähnt, dass Sie es selbst ausprobiert haben und keinen Unterschied gefunden haben, also schlug ich vor, dass Sie es vielleicht versuchen könnten (für den 2. Teil). Da Sie es als beleidigend empfanden (obwohl es nicht meine Absicht war), werde ich den beleidigenden Kommentar entfernen. – doubleDown

Antwort

11

Natürlich gibt es einen Unterschied. Die zweite Variante hat einen Block.

Eine package Deklaration legt den aktuellen Namespace für Subs und Globals fest. Dies ist normalerweise der Bereich, d. H. Der Bereich endet mit dem Ende der Datei oder der Prüfzeichenfolge oder mit einem umschließenden Block.

Die package NAME BLOCK Syntax ist nur syntaktischer Zucker für

{ package NAME; 
    ...; 
} 

und sogar kompiliert bis hinunter zu dem gleichen Opcodes.

Während die package Deklaration syntaktisch eine Anweisung ist, ist dies nicht semantisch wahr; Es legt nur Eigenschaften für die Kompilierung fest.Daher ist die letzte Anweisung des letzten Blocks die letzte Anweisung der Datei, und es gibt keinen Unterschied zwischen

package Foo; 
1; 

und

package Foo { 
    1; 
} 

WRT. die letzte Aussage.

Die package BLOCK Syntax ist vor allem interessant, weil es aussieht wie class Foo {} in anderen Sprachen, denke ich. Da der Block den Gültigkeitsbereich einschränkt, erleichtert dies auch die Verwendung von Variablen mit korrektem Bereich. Denken Sie:

package Foo; 
our $x = 1; 
package main; 
$::x = 42; 
say $x; 

Ausgang: 1, weil our lexikalisch wie my scoped ist und erklärt, nur ein Alias! Dies kann durch die Block Syntax verhindert werden:

package Foo { 
    our $x = 1; 
} 
package main { 
    $::x = 42; 
    say $x; 
} 

funktioniert wie erwartet (42), obwohl strict nicht glücklich ist.

3

Es gibt ein Unterschied :) Wenn Sie versuchen, unter zwei verschiedenen Code-Schnipsel ausgeführt wird (nur die Module importieren in ein perl-Datei)

# perlscript.pl 

use wblock; 

wblock::wbmethod(); 

ersten Code ohne Block snippet, wblock.pm

package wblock1; 
my $a =10; 
sub wbmethod1{ 
     print "in wb $a"; 
} 

package wblock; 

sub wbmethod{ 
     print "in wb1 $a"; 
} 
1; 

Zweite mit wblock.pm

package wblock1 { 
my $a =10; 
sub wbmethod1{ 
     print "in wb $a"; 
} 
1; 
} 

package wblock { 
sub wbmethod{ 
     print "in wb1 $a"; 
} 
1; 
} 

nun der Unterschied, wie Sie ist, variable gesehen haben könnte $a ist nicht für wblock Paket zur Verfügung, wenn wir BLOCK verwenden. Aber ohne BLOCK können wir $a aus einem anderen Paket verwenden, da es sich um einen Dateibereich handelt.

Mehr von perldoc selbst sagen:

Das heißt, sind die Formen ohne BLOCK bis Ende operative der aktuelle Bereich, ebenso wie die meine, Staat und unsere Mitarbeiter.

+0

Was meinen Sie mit "Sie können nicht 1; separat für jedes Paket verwenden, wenn Sie mehrere Pakete ohne BLOCK haben. Sie erhalten einen Fehler dafür."? Können Sie ein Codebeispiel posten, das den Fehler verursacht? Ich habe es versucht und es schien gut zu funktionieren. – doubleDown

+0

@doubleDown - Ich denke, Sie haben Recht. Entfernen derselben. –

+4

Die '1;' wird am Ende einer '* .pm'-Datei hinzugefügt, um dem Perl-Compiler anzuzeigen, dass die Datei korrekt geladen wurde. Es hat nichts mit Paketen zu tun. Aus diesem Grund sollte es nur eine "1;" und es sollte am Ende der Datei sein. – shawnhcorey

5
package Foo { ... } 

entspricht

{ package Foo; ... } 

, die aus den folgenden in verschieden ist, dass es ein Block

package Foo; ... 

Das ist nur zu erstellen, wenn Sie Code haben, der in der Datei folgt.


package Foo { ... } 

ist nicht entspricht

BEGIN { package Foo; ... } 

ich das es mir gewünscht hätte, aber dieser Vorschlag wurde nicht angenommen.


require (und do) verlangt, dass der letzte in der Datei ausgewertet Ausdruck einen wahren Wert zurückgibt. { ... } wertet zum letzten Wert ausgewertet innerhalb, so dass die folgende ist in Ordnung:

package Foo { ...; 1 } 

die 1; auf der Außenseite platzieren mehr Sinn für mich macht — es auf die Datei bezieht sich eher als das Paket — aber das ist nur eine Art Wahl .

1

Es gibt einen Unterschied, aber nur, wenn Sie schwer zu wartende Programmierung tun. Insbesondere, wenn Sie eine my Variable in Paketen verwenden. Die Konvention für Perl besteht darin, nur ein Paket pro Datei und das gesamte Paket in einer Datei zu haben.

1

Es gibt noch einen weiteren Unterschied, den andere Antworten nicht gegeben haben, der erklären könnte, warum es zwei gibt.

package Foo; 
sub bar { ... } 

war immer der Weg, es in Perl 5 zu tun.Die package BLOCK Syntax von

package Foo { 
    sub bar { ... } 
} 

wurde nur in Perl 5.14 hinzugefügt.

Der Hauptunterschied ist dann, dass die letztere Form sauberer ist, aber nur seit 5.14 funktioniert; Das vorherige Formular wird auf ältere Versionen zurückgreifen. Die reinere Form wurde weitgehend für die optische Sauberkeit hinzugefügt; Es hat keinen semantischen Unterschied, über den man sich Sorgen machen müsste.

Verwandte Themen