hash struktur lesen und schreiben

21/02/2010 - 17:22 von Nils Müller | Report spam
Hallo,

ich habe eine Struktur erstellt und ich bekomme einfach nicht heraus wie ich diese
Struktur auslesen kann.
Wie komme ich an den $nick und den $status? Ich erhalte immer als Antwort HASH(Zeiger)
oder ARRAY(Zeiger). Aber ich will doch den Inhalt haben. Ebenso würde ich auch gerne
den Inhalt von $nick und $status àndern können. Ich hoffe es kann mir jemand helfen.


#!/usr/bin/perl -w
use strict;
use Data::Dumper;
$\ = "";

mit_data_dumper();

sub mit_data_dumper{
my %nick_structure = ();
my $server = "";
my $nick = "";
my $status = "";
print "Lese Daten ein...";
while (<DATA>) { # nutze __DATA__ (s.u.) anstatt datei
print "input \$_: $_";
#while (<>) {
chomp; # entferne LineFeed
my ($server, $nick, $status) = split /, /;
push @{$nick_structure{$server}}, {$nick,$status};
}
print "Zeige meine Struktur an:";
print Dumper(\%nick_structure); # zeigt meine Datenstruktur an

foreach $server (sort keys %nick_structure) {
print "$server: ";
my @nick = @{$nick_structure{$server}};
print join ', ', sort @nick; # HASH(Zeiger)
}

$server = "freenode";
my $test = @{$nick_structure{$server}}[0];
print [$test]; # ARRAY(Zeiger)
}

__DATA__
freenode, paul, online
freenode, fritz, online
fu-berlin, paul, away
freenode, hans, offline
fu-berlin, harry, online
 

Lesen sie die antworten

#1 Christian Winter
21/02/2010 - 18:04 | Warnen spam
Nils Müller schrieb:
Hallo,

ich habe eine Struktur erstellt und ich bekomme einfach nicht heraus wie ich diese
Struktur auslesen kann.
Wie komme ich an den $nick und den $status? Ich erhalte immer als Antwort HASH(Zeiger)
oder ARRAY(Zeiger). Aber ich will doch den Inhalt haben. Ebenso würde ich auch gerne
den Inhalt von $nick und $status àndern können. Ich hoffe es kann mir jemand helfen.


#!/usr/bin/perl -w
use strict;
use Data::Dumper;
$\ = "";

mit_data_dumper();

sub mit_data_dumper{
my %nick_structure = ();
my $server = "";
my $nick = "";
my $status = "";
print "Lese Daten ein...";
while (<DATA>) { # nutze __DATA__ (s.u.) anstatt datei
print "input \$_: $_";
#while (<>) {
chomp; # entferne LineFeed
my ($server, $nick, $status) = split /, /;
push @{$nick_structure{$server}}, {$nick,$status};
}



Hier erzeugst du (via Autovivication) als Hasheintrag eine
Liste die wiederum Hashreferenzen enthàlt.

$nick_stucture{$server} ist der Eintrag, durch das @{...}
sagst du Perl dass es den Eintrag als Liste dereferenzieren
soll, und Perl ist so hilfreich, diese Referenz auf die Liste
automatisch zu generieren.

Die Liste enthàlte dann Hashreferenzen, wobei es vielleicht
schon ein wenig klarer wird, wenn man stattdessen
push @{$nick_structure{$server}}, { $nick => $status }
schreibt.

Ich bin mir Anhand deiner Beschreibung oben nicht ganz sicher
ob du das so überhaupt willst, oder ob nicht ein Hash of Hashes
allein reicht. Dann müsste oben aber stehen
$nick_structure{$server}->{$nick} = $status;
und du könntest dann mit
foreach my $server ( keys %nick_structure ) {
foreach my $user ( keys %{$nick_structure{$server}} ) {
print $user . ": " . $nick_structure{$server}->{$user} . $/;
}
die Eintràge auslesen.

print "Zeige meine Struktur an:";
print Dumper(\%nick_structure); # zeigt meine Datenstruktur an

foreach $server (sort keys %nick_structure) {
print "$server: ";
my @nick = @{$nick_structure{$server}};
print join ', ', sort @nick; # HASH(Zeiger)



@nick enthàlt jetzt die Liste mit den Hashreferenzen. D.h.
es sieht etwa so aus:
( {"paul" => "online"}, {"fritz" => "online"}, {"hans" => "offline"} )
und làsst sich in einem Loop auflösen
foreach my $entry ( @nick ) {
while( my( $user, $status ) = each %{$entry} ) {
print $user . ": " . $status . $/;
# Oder lànger über:
# foreach my $user ( keys %{$entry} ) {
# print $user . ":" . $entry->{$user} . $/;
# }
}
}
Das macht so nicht richtig Sinn, ausser wenn du mehr Infos zum User
ablegen möchtest, dann solltest du entweder den Benutzer wie
in meinem Beispiel darüber als Hash Key verwenden und einen
Hash mit den Info-Attributen als Keys zuweisen, oder aber
eine Hashreferenz mit benannten Keys verwenden:
push @{$nick_structure{$server}}, {
"name" => $nick,
"status" => $status
};
Darauf kannst du dann spàter mit
foreach my $entry ( @nick ) {
print $entry->{"name"} . ": " . $entry->{"status"} . $/;
}
zugreifen.

}

$server = "freenode";
my $test = @{$nick_structure{$server}}[0];
print [$test]; # ARRAY(Zeiger)



Das ist klar, ein "print [];" würde nichts anderes ausgeben, da
print() keine Referenzen expandiert (und durch die eckigen Klammern
erzeugst du eine Arrayreferenz).
$test enthàlt jetzt eine Hashref {"paul" => "online"}, d.h.
um an den Inhalt zu kommen ohne den Namen des Users zu wissen,
musst du jetzt wieder über "keys %{$test}" bzw. "each %{$test}"
gehen. "$test->{'hans'}" lieftert dir aber richtig "offline" zurück.

}

__DATA__
freenode, paul, online
freenode, fritz, online
fu-berlin, paul, away
freenode, hans, offline
fu-berlin, harry, online



Am besten siehst du dir einmal "perldoc perlreftut" an, dort werden
Anwendungsfàlle wie deiner bis ins Detail erklàrt.

-Christian

Ähnliche fragen