Kurz: Arrays und Hashes enthalten nur Skalare. Für verschachtelte Strukturen braucht man Referenzen: Skalare, die auf andere Daten zeigen.
Teil des Kurses Perl
Referenzen
Arrays und Hashes enthalten nur Skalare. Für verschachtelte Strukturen braucht man Referenzen: Skalare, die auf andere Daten zeigen.
use strict; use warnings;
my @liste = (1, 2, 3);
my %hash = (a => 1, b => 2);
my $aref = \@liste; # Referenz auf Array
my $href = \%hash;
my $cref = sub { "Hallo $_[0]" };
my $sref = \"Text";
print "$$aref[0] ${$aref}[1] $aref->[2]\n"; # drei Schreibweisen
print "$href->{a} $$href{b}\n";
print scalar(@$aref), " Elemente\n";
print join(",", sort keys %$href), "\n";
print $cref->("Welt"), "\n";
print $$sref, "\n";
print ref($aref), " ", ref($href), " ", ref($cref), " ", ref($sref), " ", ref(\$aref), "\n";
push @$aref, 4;
print "@liste\n"; # das Original wurde geändert
my @kopie = @$aref; # echte Kopie
$kopie[0] = 99;
print "$liste[0]\n";Ausgabe:
1 2 3
1 2
3 Elemente
a,b
Hallo Welt
Text
ARRAY HASH CODE SCALAR REF
1 2 3 4
1Verschachtelte Strukturen
Mit anonymen Arrays [...] und Hashes {...} baust du beliebig tiefe Daten:
use strict; use warnings;
my %firma = (
name => "Emzett",
mitarbeiter => [
{ name => "Mia", rolle => "Dev", skills => ["perl", "sql"] },
{ name => "Tom", rolle => "Ops", skills => ["bash"] },
],
adresse => { ort => "Berlin", plz => "10115" },
);
print "Firma: $firma{name} in $firma{adresse}{ort}\n";
print "Erste Person: $firma{mitarbeiter}[0]{name}\n";
print "Skills von Mia: @{ $firma{mitarbeiter}[0]{skills} }\n";
push @{ $firma{mitarbeiter} }, { name => "Zoe", rolle => "Dev", skills => [] };
print "Anzahl: ", scalar @{ $firma{mitarbeiter} }, "\n";
for my $m (@{ $firma{mitarbeiter} }) {
printf "%-4s %-4s %s\n", $m->{name}, $m->{rolle}, join("/", @{ $m->{skills} }) || "-";
}
my @devs = grep { $_->{rolle} eq "Dev" } @{ $firma{mitarbeiter} };
print join(", ", map { $_->{name} } @devs), "\n";
my %nach_rolle;
push @{ $nach_rolle{ $_->{rolle} } }, $_->{name} for @{ $firma{mitarbeiter} }; # Autovivification
print join("; ", map { "$_: @{ $nach_rolle{$_} }" } sort keys %nach_rolle), "\n";
print exists $firma{adresse}{strasse} ? "Straße" : "keine Straße", "\n";
my @matrix = ([1, 2, 3], [4, 5, 6]);
print $matrix[1][2], " ", scalar(@{ $matrix[0] }), " ", join(",", map { $_->[0] } @matrix), "\n";Ausgabe:
Firma: Emzett in Berlin
Erste Person: Mia
Skills von Mia: perl sql
Anzahl: 3
Mia Dev perl/sql
Tom Ops bash
Zoe Dev -
Mia, Zoe
Dev: Mia Zoe; Ops: Tom
keine Straße
6 3 1,4Autovivification: Perl legt fehlende Zwischenebenen automatisch an, sobald du darauf schreibst ($h{a}{b}{c} = 1).
Postfix-Dereferenzierung
Ab Perl 5.24 lesbarer:
use v5.36;
my $a = [3, 1, 2];
my $h = { x => 1, y => 2 };
say join ",", sort { $a <=> $b } $a->@*;
say scalar $a->@*;
say join ",", sort keys $h->%*;
say "Letzter Index: ", $a->$#*;
my @teil = $a->@[0, 1];
say "@teil";Ausgabe:
2,1,3
3
x,y
Letzter Index: 2
3 1Daten ausgeben: Data::Dumper
use strict; use warnings;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Indent = 1;
my $daten = { name => "Mia", liste => [1, 2], tief => { a => undef } };
print Dumper($daten);
$Data::Dumper::Terse = 1;
$Data::Dumper::Indent = 0;
print Dumper([1, { k => "v" }]), "\n";Ausgabe:
$VAR1 = {
'liste' => [
1,
2
],
'name' => 'Mia',
'tief' => {
'a' => undef
}
};
[1,{'k' => 'v'}]Kopieren und Gleichheit
use strict; use warnings;
use Storable qw(dclone);
my $orig = { liste => [1, 2, 3] };
my $flach = { %$orig }; # flache Kopie: Liste wird geteilt
my $tief = dclone($orig); # tiefe Kopie
push @{ $orig->{liste} }, 4;
print scalar @{ $flach->{liste} }, " ", scalar @{ $tief->{liste} }, "\n";
print "gleiche Referenz\n" if $orig == $orig;
print "verschiedene Referenzen\n" if $orig != $tief;Ausgabe:
4 3
gleiche Referenz
verschiedene ReferenzenMerke
\@a,\%h,\&fbilden Referenzen;[...]und{...}erzeugen anonyme- Zugriff:
$r->[0],$r->{key},@{$r},%{$r},$r->@* - Verschachtelte Daten:
$d{liste}[0]{name} ref()zeigt den Typ;Data::Dumpergibt Strukturen aus- Flache vs. tiefe Kopie (
Storable::dclone)
Übungsaufgabe
Baue eine Liste von Büchern (Hashes) und gruppiere sie nach Autor in einem Hash von Arrays.
Quiz zur Selbstkontrolle
Wie greifst du auf das erste Element einer Array-Referenz $r zu?
- $r->[0] (richtig)
- $r[0]
- @r[0]
- $r.0
Wofür ist Data::Dumper?
- Strukturen lesbar ausgeben (richtig)
- Datenbanken sichern
- Dateien löschen
- Speicher füllen
?
- Eine Referenz auf ein anonymes Array (richtig)
- Ein Array
- Einen Hash
- Eine Funktion
Weiter im Kurs
Zurück: Dateien, Verzeichnisse und Ein-/Ausgabe
Weiter: Module, CPAN und Pakete
Alle Kapitel: Perl im Überblick