Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Datentypen

Perl hat drei grundlegende Datentypen: Skalare, Arrays und Hashes. PetaPerl implementiert diese mit identischer Semantik zu Perl 5.

Skalare

Skalare sind der grundlegende Datentyp in Perl und enthalten einen einzelnen Wert. Der Variablenname beginnt mit $.

my $number = 42;
my $string = "hello";
my $float = 3.14;
my $ref = \@array;

Skalartypen

Intern stellt PetaPerl Skalare als Enum mit folgenden Varianten dar:

TypBeschreibungBeispiel
UndefUndefinierter Wertundef
IvGanzzahl (i64)42, -17
UvVorzeichenlose Ganzzahl (u64)Grosse positive Zahlen
NvGleitkommazahl (f64)3.14, 1.5e10
PvUnveraenderliche Zeichenkette (Arc<str>)Konstanten, Literale
PvBufVeraenderliche Zeichenkette (Arc<String>).=-Ziele, $_
RvReferenz\$x, \@arr, \%hash
AvArrayErzeugt durch []
HvHashErzeugt durch {}

Dynamische Typisierung: Ein Skalar kann seinen Typ waehrend der Ausfuehrung aendern.

my $x = 42;          # Ganzzahl
$x = "hello";        # Jetzt eine Zeichenkette
$x = 3.14;           # Jetzt eine Gleitkommazahl

Skalarer Kontext

Operationen, die einen einzelnen Wert erwarten, erzwingen skalaren Kontext:

my $count = @array;          # Array-Laenge
my $last = (1, 2, 3);        # Letztes Element (3)
if (@array) { ... }          # Wahr wenn nicht leer

Spezielle Skalare

WertBeschreibung
undefUndefinierter Wert
0Numerische Null, Zeichenkette “0”
""Leere Zeichenkette

Wahrheitswerte: Diese sind im booleschen Kontext falsch: undef, 0, "0", "". Alles andere ist wahr.

if ($value) { ... }          # Falsch bei undef, 0, "0" oder ""
if (defined $value) { ... }  # Falsch nur bei undef

Arrays

Arrays sind geordnete Listen von Skalaren. Variablennamen beginnen mit @.

my @numbers = (1, 2, 3, 4, 5);
my @words = qw(foo bar baz);
my @empty = ();

Array-Zugriff

my $first = $numbers[0];     # Erstes Element (Index 0)
my $last = $numbers[-1];     # Letztes Element
$numbers[5] = 6;             # Element setzen

Beachte den Sigilwechsel: Verwende $ fuer den Zugriff auf ein einzelnes Element, da ein Skalar zurueckgegeben wird.

Array-Laenge

my $length = @array;         # Skalarer Kontext
my $length = scalar @array;  # Explizit skalarer Kontext
my $max_index = $#array;     # Hoechster Index (Laenge - 1)

Array-Operationen

push @arr, $value;           # Anhaengen
my $value = pop @arr;        # Letztes entfernen
my $value = shift @arr;      # Erstes entfernen
unshift @arr, $value;        # Voranstellen

splice @arr, $offset, $len, @replacement;  # Allgemeines Entfernen/Einfuegen

Array-Scheiben

Mehrere Elemente auf einmal extrahieren:

my @subset = @arr[0, 2, 4];  # Elemente 0, 2, 4
my @range = @arr[0..5];      # Elemente 0 bis 5
@arr[1, 3] = (10, 20);       # Mehreren Elementen zuweisen

Listenkontext

Operationen, die mehrere Werte erwarten, erzwingen Listenkontext:

my @copy = @original;        # Array-Kopie
my ($a, $b, $c) = (1, 2, 3); # Listenzuweisung
my @results = function();    # Funktion gibt Liste zurueck

Array-Referenzen

Referenzen auf Arrays erzeugen:

my $aref = \@array;          # Referenz auf bestehendes Array
my $aref = [1, 2, 3];        # Anonyme Array-Referenz

Zugriff ueber Referenz:

my $elem = $aref->[0];       # Erstes Element
my @copy = @$aref;           # Dereferenzierung zum Array
push @$aref, $value;         # Push ueber Referenz

Hashes

Hashes sind ungeordnete Schluessel-Wert-Paare. Variablennamen beginnen mit %.

my %user = (
    name => "John",
    age => 30,
    email => "john@example.com",
);

Hash-Zugriff

my $name = $user{name};      # Wert abrufen
$user{city} = "NYC";         # Wert setzen

Sigilwechsel: Verwende $ fuer den Zugriff auf ein einzelnes Element (es wird ein Skalar zurueckgegeben).

Hash-Operationen

my @keys = keys %hash;       # Alle Schluessel
my @values = values %hash;   # Alle Werte
while (my ($k, $v) = each %hash) { ... }  # Iterieren

if (exists $hash{key}) { ... }  # Existenz pruefen
my $val = delete $hash{key};    # Entfernen und zurueckgeben

Hash-Scheiben

Mehrere Werte auf einmal extrahieren:

my @vals = @hash{qw(name age)};         # Werte fuer Schluessel
@hash{qw(x y)} = (10, 20);              # Mehrfachzuweisung

Hinweis: Hash-Scheiben verwenden das @-Sigil, da sie eine Liste zurueckgeben.

Hash-Referenzen

Referenzen auf Hashes erzeugen:

my $href = \%hash;           # Referenz auf bestehenden Hash
my $href = { key => "val" }; # Anonyme Hash-Referenz

Zugriff ueber Referenz:

my $val = $href->{key};      # Wert abrufen
$href->{new} = "value";      # Wert setzen
my @keys = keys %$href;      # Dereferenzierung zum Hash

Referenzen

Referenzen sind Skalare, die auf andere Daten verweisen.

Referenzen erzeugen

my $scalar_ref = \$scalar;
my $array_ref = \@array;
my $hash_ref = \%hash;
my $code_ref = \&sub;
my $anon_array = [1, 2, 3];
my $anon_hash = { a => 1, b => 2 };
my $anon_sub = sub { ... };

Dereferenzierung

my $value = $$scalar_ref;    # Skalar-Dereferenzierung
my @array = @$array_ref;     # Array-Dereferenzierung
my %hash = %$hash_ref;       # Hash-Dereferenzierung
my $result = &$code_ref();   # Code-Dereferenzierung

Pfeilnotation (bevorzugt fuer Klarheit):

my $elem = $array_ref->[0];
my $val = $hash_ref->{key};
my $result = $code_ref->(@args);

Referenztypen

Referenztyp mit ref pruefen:

my $type = ref $ref;
# Gibt zurueck: 'SCALAR', 'ARRAY', 'HASH', 'CODE', 'REF' oder '' (keine Referenz)

Verschachtelte Datenstrukturen

Referenzen ermoeglichen komplexe Datenstrukturen:

my $data = {
    users => [
        { name => "John", age => 30 },
        { name => "Jane", age => 25 },
    ],
    config => {
        debug => 1,
        timeout => 30,
    },
};

my $name = $data->{users}->[0]->{name};  # "John"

Autovivifikation

Perl erzeugt automatisch Zwischenreferenzen:

my %hash;
$hash{a}{b}{c} = 1;          # Erzeugt verschachtelte Hashes automatisch
my $val = $hash{x}[0];       # Erzeugt Array-Referenz unter $hash{x}

Typumwandlungen

Perl fuehrt automatische Typumwandlungen kontextabhaengig durch.

Zeichenkette zu Zahl

my $x = "42";
my $y = $x + 10;             # 52 (Zeichenkette -> Zahl)

Zahl zu Zeichenkette

my $x = 42;
my $s = "Wert: $x";          # "Wert: 42" (Zahl -> Zeichenkette)

Zeichenkettenverkettung

my $result = 10 . 20;        # "1020" (beide -> Zeichenkette)

Boolescher Kontext

if ("0")    { ... }          # Falsch
if ("00")   { ... }          # Wahr
if (0)      { ... }          # Falsch
if (0.0)    { ... }          # Falsch
if ("")     { ... }          # Falsch
if (undef)  { ... }          # Falsch

Typeglobs

Typeglobs sind ein spezieller Typ, der Eintraege fuer alle Variablentypen mit demselben Namen enthalten kann.

*name = \$scalar;            # Glob auf Skalar aliasieren
*name = \&sub;               # Glob auf Unterprogramm aliasieren

Werden hauptsaechlich fuer Symboltabellenmanipulation und Importvorgaenge verwendet.

PetaPerl-spezifische Implementierung

Speicherdarstellung

PetaPerl verwendet effiziente interne Darstellungen:

Skalare: Rust-Enum mit Varianten fuer jeden Typ. Zwei Zeichenkettendarstellungen optimieren fuer verschiedene Zugriffsmuster.

#![allow(unused)]
fn main() {
pub enum Sv {
    Undef,
    Iv(i64),                 // Ganzzahl
    Uv(u64),                 // Vorzeichenlos
    Nv(f64),                 // Gleitkomma
    Pv(Arc<str>, u32),       // Unveraenderliche Zeichenkette + virtuelle Laenge (O(1) chomp)
    PvBuf(Arc<String>),      // Veraenderliche Zeichenkette (COW ueber Arc::make_mut)
    Rv(RvInner),             // Referenz
    Av(Av),                  // Array
    Hv(Hv),                  // Hash
    // ... weitere Typen
}
}

Duale Zeichenkettendarstellung: Pv wird fuer Konstanten und Literale verwendet – die virtuelle Laenge u32 ermoeglicht O(1)-chomp ohne Aenderung der gemeinsam genutzten Zeichenkette. PvBuf wird fuer veraenderliche Zeichenketten verwendet (Standard fuer new_string()) – Arc::make_mut() bietet Copy-on-Write-Semantik ohne Allokation bei nicht geteiltem Besitz.

Arrays: Dynamische Vektoren mit effizienten push/pop-Operationen.

Hashes: Optimierte Hashtabellen mit schneller Schluesselsuche.

Gemeinsamer Besitz

Zeichenketten-Skalare verwenden Arc<str> (atomare Referenzzaehlung):

  • Guenstiges Klonen (nur Zaehler erhoehen)
  • Thread-sicheres Teilen fuer parallele Ausfuehrung
  • Haeufig verwendete Zeichenketten koennen Speicher teilen

Aliasing-Unterstuetzung

PetaPerl implementiert @_-Aliasing korrekt:

  • Argumente sind Aliase auf die Variablen des Aufrufers
  • Aenderungen schreiben direkt in das Original
  • Verwendet SvCell fuer veraenderliche Indirektion
sub modify {
    $_[0] = "changed";       # Aendert die Variable des Aufrufers
}

my $x = "original";
modify($x);
print $x;                    # "changed"

Leistungsmerkmale

OperationKomplexitaetAnmerkungen
SkalarzuweisungO(1)Zeichenkette nutzt Arc (keine Kopie)
Array push/popO(1) amortisiertDynamisches Wachstum
Array shift/unshiftO(n)Elemente muessen verschoben werden
Hash-ZugriffO(1) durchschnittlichOptimierte Hash-Funktion
Hash-EinfuegenO(1) durchschnittlichMit Wachstum

Parallele Ausfuehrung

PetaPerls Parallelisierungsmodell:

  • Jeder Thread erhaelt seinen eigenen lexikalischen Pad (keine gemeinsame Mutation)
  • Array- und Hash-Operationen sind thread-sicher
  • Arc<str>-Zeichenketten koennen sicher zwischen Threads geteilt werden
  • Parallelitaet auf Schleifenebene erfordert keine globalen Sperren

Kontextsensitivitaet

Perls Kontextsystem bestimmt, wie Ausdruecke ausgewertet werden.

Skalarer Kontext

Erzwingt Auswertung als Einzelwert:

my $count = @array;          # Laenge
my $last = (1, 2, 3);        # Letztes Element
my $concat = (1, 2, 3);      # 3

Listenkontext

Erzwingt Auswertung als Mehrfachwert:

my @copy = @array;           # Alle Elemente
my @results = func();        # Alle Rueckgabewerte
my ($a, $b) = (1, 2, 3);     # Erste zwei Elemente

Void-Kontext

Das Ergebnis wird verworfen:

func();                      # Rueckgabewert ignoriert
print "hello";               # Keine Zuweisung

Kontextweitergabe

my @arr = (1, 2, 3);

# Skalarer Kontext
my $x = keys @arr;           # keys im skalaren Kontext -> Anzahl

# Listenkontext
my @k = keys @arr;           # keys im Listenkontext -> alle Schluessel

# Funktionsargument-Kontext
func(@arr);                  # Listenkontext
func(scalar @arr);           # Skalarer Kontext (explizit)

Konstanten

Konstanten sind unveraenderliche Werte.

Literalkonstanten

42                           # Ganzzahl
3.14                         # Gleitkommazahl
"string"                     # Zeichenkette
qw(a b c)                    # Liste von Zeichenketten

Benannte Konstanten

use constant PI => 3.14159;
use constant MAX => 100;
use constant {
    RED   => 0xFF0000,
    GREEN => 0x00FF00,
    BLUE  => 0x0000FF,
};

Konstantenfaltung zur Uebersetzungszeit

PetaPerl fuehrt Konstantenfaltung zur Uebersetzungszeit durch:

my $x = 2 + 3;               # Wird zu 5 gefaltet
my $len = length("hello");   # Wird zu 5 gefaltet
my $sub = substr("text", 0, 2);  # Wird zu "te" gefaltet

Diese Optimierung eliminiert Laufzeitberechnungen fuer konstante Ausdruecke.

Spezielle Typen

Code-Referenzen

Unterprogramme koennen referenziert und dynamisch aufgerufen werden:

my $coderef = sub { return $_[0] * 2 };
my $result = $coderef->(21);  # 42

my $coderef = \&existing_sub;
$coderef->(@args);

Dateihandles

Dateihandles sind spezielle Skalare:

open my $fh, '<', $file or die $!;
my $line = <$fh>;
close $fh;

Globs

Typeglobs verweisen auf Symboltabelleneintraege:

*alias = *original;          # Alle Typen aliasieren
*func = sub { ... };         # Unterprogramm installieren

Siehe auch

  • perlop - Operatoren, die mit diesen Typen arbeiten
  • perlfunc - Funktionen zur Datenmanipulation
  • perlref - Mehr zu Referenzen (Perl-5-Dokumentation)