Samstag, 29. Dezember 2007

Perl 5.10: use feature qw/state/;

Eines der neuen Features von Perl 5.10 ist die vereinfachte Erzeugung statischer bzw. persistenter Variablen.

Während man bisher closures verwenden musste, um statische Variablen zu erzeugen, gibt es jetzt in Perl 5.10 das feature state.

Beispiel:

Perl 5.8.8


use strict;
use warnings;

{ ## Start of closure
my $counter = 0;
sub next_counter {
$counter++;
return $counter;
}
} ## End of closure

for ( 1 .. 5 ) {
print next_counter() ,"\n";
}

Warum $counter, die persistente Variable, hier nur ein einziges Mal initialisiert wird, also nur einmal auf Null gesetzt wird, ist für Einsteiger (und auch einige Profis) meist nur sehr schwer bis gar nicht zu verstehen. Hinweis: Subroutinen sind global im aktuellen Namensraum (Package).

Perl 5.10.0

use strict;
use warnings;
use feature qw/say state/;

sub next_counter {
state $counter = 0;
$counter++;
return $counter;
}

for ( 1 .. 5 ) {
say next_counter();
}

Die persistente Variable $counter ist jetzt als statisch gekennzeichnet und befindet sich in der Subroutine und nicht außerhalb in einem Block. Das ist doch viel lesbarer, einfacher zu verstehen und zu warten.

state funktioniert so ähnlich wie my, die Variable wird jedoch erst bei der ersten Verwendung initialisiert und nicht schon bei der Deklaration.

Weiterhin benötigt state wesentlich weniger Hauptspeicher als die closure-Version.

state-Variablen können auch in tief verschachtelten Schleifen oder Subroutinen verwendet werden wie der folgende Pseudocode verdeutlichen soll:

for my $x ( 1 .. 5 ){
for my $y ( 1 .. 5 ) {
state %seen;
next if $seen{$x}{$y}++;
}
}


Die neuen Features von Perl 5.10 werden aus Gründen der Rückwärtskompatibilität nicht automatisch geladen, sondern müssen explizit wie folgt eingebunden werden:

Entweder bestimmte Features, hier state und say, einbinden

use feature qw/say state/;

oder alle neuen Features verwenden

use feature qw/:5.10/;


Vorhergehende Artikel von mir zu den neuen Features in Perl 5.10:

Keine Kommentare: