Blog

Auf dem Weg zu Perl 5.36 – gesammelte Werke

25.05.2022 // Renée Bäcker

Zum Abschluss der kleinen Blogpost-Serie ein Artikel der noch ein paar Änderungen aufsammelt, die nicht in die anderen Artikel gepasst haben.

Oktalzahlen

Fangen wir mit einer Kleinigkeit an: Es gibt eine neue (zusätzliche) Syntax um Oktalzahlen in Perl-Code zu schreiben:

my $file_permissions = 0o755;
chmod $file_permissions, '/tmp/test.pl';

say sprintf "%d", $file_permissions; # 493

Für die Verwendung von Oktalzahlen gibt es mehrere Gründe. Bisher konnte man Oktalzahlen einfach mit 0 beginnen, also

my $file_permissions = 0755;
chmod $file_permissions, '/tmp/test.pl';

say sprintf "%d", $file_permissions; # 493

Das hat aber einen großen Nachteil: Gerade für Perl-Einsteiger ist nicht gleich erkennbar dass das eine Oktalzahl ist. Nicht nur einmal habe ich solchen Code gesehen:

my %hash = (
  001 => 'eins',
  010 => 'zehn',
  100 => 'hundert',
);

Hier sollten in der Regel die führenden Nullen einfach zur Formatierung der Schlüssel verwendet werden. Aber was liefert ein

say "$_ => $hash{$_}" for sort keys %hash;

Etwas anderes als manche vielleicht vermuten würden:

1 => eins
100 => hundert
8 => zehn

Ups.

Die 0o... Schreibweise fügt sich auch besser in die bestehende Syntax für Hexadezimal- und Binärzahlen ein:

my $hex = 0xdeadaffe;
my $bin = 0b100;

Mehrere Laufvariablen in einer for-Schleife

Das nächste Thema ist ein ganz Kleines, aber eines auf das ich mich richtig freue: Es wird möglich sein, bei einer Iteration in einer for-Schleife mehr als nur ein Element aus einer Liste zu holen. Eine Standard-*for*-Schleife:

my @numbers = ( 1 .. 16 );
for my $nr ( @numbers ) {
    say "$nr";
}

Die Aufgabe ist jetzt, diese Liste in vier Reihen zu je vier Zahlen auszugeben. Also nimmt man eine Laufvariable und bricht die Zeile nach jeweils 4 Elementen selbst um:

my @numbers = ( 1 .. 16 );
my $cnt = 1;
for my $nr ( @numbers ) {
    print "$nr ";
    print "\n" if $cnt++ % 4 == 0;
}

Einfacher geht das jetzt in Perl 5.36:

my @numbers = ( 1 .. 16 );
for my ($first, $second, $third, $fourth) ( @numbers ) {
    say "$first $second $third $fourth";
}

Das Feature ist aber noch als experimentell markiert. Hier jetzt aber mal die Aufforderung: Nutzt auch experimentelle Features - auch in produktivem Code. Experimentell heißt nicht, dass man es nicht nutzen soll, sondern dass sich an der Implementierung ein paar Sachen ändern können. In vielen Fällen verlässt das Feature aber unverändert oder nur mit minimal Änderungen den experimentellen Status. Eine schöne Übersicht über die Experimente gibt es übrigens in der perlexperiment-Dokumentation.

Code-Ausführung bis zum Ende des Scopes verzögern

Das abschließende Thema sind defer-Blöcke. Diese Blöcke kann man an jeder Stelle im Programmcode definieren; sie werden aber nicht gleich ausgeführt, sondern erst beim Verlassen des Gültigkeitsbereichs.

Ein kleines Beispiel:

use feature 'defer';
 
{
    say "This happens first";
    defer { say "This happens last"; }
 
    say "And this happens inbetween";
}

Auch wenn der defer-Block in Zeile 5 vor dem say in Zeile 7 definiert wurde, wird dieser Gültigkeitsbereich in Zeile 8 verlassen wird. Die Ausgabe ist also

This happens first
And this happens inbetween
This happens last

Solche defer-Blöcke eignen sich sehr gut, um möglichst früh festzulegen, was später mal passieren soll. Ein Beispiel: Nach dem Aufbau einer Datenbankverbindung möchte man schon direkt sagen, dass bei Verlassen des Blocks die Verbindung abgebaut werden soll (und vielleicht noch weitere Dinge gemacht werden sollen) .

use feature 'defer';
 
{
   my $dbh = DBI->connect( ... ) or die "Cannot connect";
   defer { $dbh->disconnect; }
 
   my $sth = $dbh->prepare( ... ) or die "Cannot prepare";
   defer { $sth->finish; }
 
   #...
}

Hier muss man nicht erst zig Seiten an Code runterscrollen, um zu erkennen, dass auch an das disconnect gedacht wurde. Es steht direkt bei dem Verbindungsaufbau.

Die defer-Blöcke werden in umgekehrter Reihenfolge ihrer Definition ausgeführt.

Perl 5.36 wird noch einiges mehr bringen als das, was in den vergangenen Blogartikeln gezeigt wurde. Wir freuen uns schon auf das neue Release und all die Änderungen, die damit einhergehen.


Permalink: