Mit Perl 5.36 gibt es ein neues Pragma: builtin
. Damit lassen sich neue Hilfsfunktionen in das Skript/Modul importieren. Derzeit bietet das Pragma folgende Hilfsfunktionen:
use v5.35;
use builtin qw(true false is_bool);
no warnings 'experimental::builtin';
my $true = true;
my $false = false;
say is_bool( $true );
say is_bool( $false );
Aktuell ist das Pragma als experimentell eingestuft. Beim Einbinden des Pragmas muss angegeben werden, welche Funktionen importiert werden sollen (alternativ kann man bei den Aufrufen einfach den vollqualifizierten Namen angeben, z.B. builtin::true()
.
true
und false
erstellt jeweils Werte, die im boolschen Kontext wahr bzw. unwahr liefern. In Strings und/oder Berechnungen werden aber die Standardwerte
für wahr/*unwahr* genommen: 1 bzw. "" (Leerstring).
Es gibt einen Unterschied zu den Werten, die man bisher typischerweise für die boolschen Werte verwendet hat: In den Interna der Variablen wird nun zur Laufzeit gespeichert, dass es sich um boolsche Werte handelt:
use Devel::Peek;
my $true = builtin::true;
my $false = builtin::false;
Dump( $true ); Dump( $false );
Liefert
SV = PVNV(0x5653938f9380) at 0x56539391f968
[...]
PV = 0x565392196bc4 "1" [BOOL PL_Yes]
[...]
SV = PVNV(0x5653938f93a0) at 0x56539391f938
[...]
PV = 0x565392196bc3 "" [BOOL PL_No]
[...]
Man sieht hier den Zusatz [BOOL PL_{Yes|No}]
. Diese Zusatzinformation wird auch von builtin::is_bool
ausgewertet. Damit kann man unterscheiden, ob die 1
ein boolscher Wert ist oder einfach die Zahl 1
:
my $zahl = 1;
my $wahr = builtin::true;
print sprintf '$zahl ist bool: %s, $wahr ist bool: %s',
builtin::is_bool( $zahl ),
builtin::is_bool( $wahr );
mit der Ausgabe
$zahl ist bool: , $wahr ist bool: 1
Auf Referenzen arbeiten einige Hilfsfunktionen:
Diese Funktionen sind auch in Scalar::Util verfügbar, deshalb zeige ich hier nur die – in meinen Augen – wichtigsten Funktionen weaken, blessed und reftype.
Mit blessed
kann man herausfinden, ob eine Variable eine ge*blessed*e Referenz (sprich ein Objekt) ist. Ist das der Fall, wird der entsprechende Paketname zurückgeliefert:
use builtin qw(blessed);
no warnings 'experimental::builtin';
use Math::BigInt;
my $int = Math::BigInt->new(2022);
if ( blessed $int ) {
say '$int is blessed';
say "package: ", blessed $int;
}
liefert
$ perl blessed.pl
$int is blessed
package: Math::BigInt
Mit reftype
bekommt man den Namen der Datenstruktur, auf die die Referenz verweist. Die meisten werden die Funktion ref
kennen:
my $array_ref = [];
say ref( $array_ref ); # liefert ARRAY
Soweit so gut. Sobald es aber ein Objekt ist, wird nicht der Name der Datenstruktur ausgegeben, sondern der Name des Pakets:
my $array_object = bless [], 'Array';
say ref( $array_object ); # liefert Array, also den Paketnamen
reftype
liefert in jedem Fall den Namen der Datenstruktur:
my $array_object = bless [], 'Array';
say reftype( $array_object ); # liefert ARRAY
Werden komplexe Datenstrukturen aufgebaut, kann es schnell passieren, dass man zirkuläre Referenzen aufbaut:
my %hash_eins;
my %hash_zwei = ( eins => \%hash_eins );
$hash_eins{zwei} = \%hash_zwei;
Damit hat man ein Speicherleck erzeugt. Perl nutzt einen Referenzzähler, um Speicher freizugeben. Und der kann hier nie auf 0 gehen, da in einer zirkulären Referenz immer A auf B verweist und B auf A.
In so einem Fall kann man weaken
nutzen. Damit wird der Referenzzähler der Variable nicht hochgezählt:
my %hash_eins;
my %hash_zwei = ( eins => \%hash_eins );
$hash_eins{zwei} = \%hash_zwei;
builtin::weaken( $hash_eins{zwei} );
Zu diesem Problem werden wir noch einen weiteren Blogartikel schreiben.
Eine kleine Funktionalität, die aber auch bei den Entwicklern von Perl viel Diskussionen hervorgerufen hat. Es gibt auf CPAN etliche Implementierungen davon. Leerzeichen am Anfang und am Ende eines Strings entfernen.
Warum gab es diese Diskussionen? Es ging hauptsächlich darum, was das trimmen genau machen soll. Einfach nur Leerzeichen oder noch andere Whitespaces? Soll der Nutzer die Möglichkeit haben, die zu entfernenden Zeichen selbst festzulegen? Soll das ganze Inplace (wie s///
) passieren oder soll der veränderte Wert zurückgegeben werden?
Mit trim
werden die Whitespaces am Anfang und am Ende eines Strings entfernt und der veränderte Wert wird zurückgegeben:
use builtin qw(blessed);
no warnings 'experimental::builtin';
my $t = "\t \ntest \n ";
say ">>",$t,"<<";
my $trimmed = builtin::trim($t); s
ay ">>$trimmed<<"
liefert die Ausgabe
>>
test
<<
>>test<<
Im Laufe der Zeit werden sicher noch etliche nützliche Hilfsfunktionen im builtin::
-Namensraum landen. Schon in Perl 5.36 sind viele Helferlein enthalten, die schon so oft vermisst wurden. Die Vorfreude auf das neue Release wächst.
Permalink: /2022-05-20-auf-dem-weg-zu-perl-536-builtin