Schrift
[thread]8758[/thread]

Kurze Frage zu Hash in Hash

Leser: 1


<< >> 10 Einträge, 1 Seite
Lightman
 2007-02-14 17:10
#74327 #74327
User since
2007-01-31
57 Artikel
BenutzerIn
[default_avatar]
Hallo Community,

ich möchte gerne einen Hash im Hash realisieren, was aber leider nicht so ganz klappt:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
sub new {
   my ($class, %args) = @_;

   # ...

   my $self = bless {
       # ...
       # Das soll der Hash sein:
       _config => {},
   }, $class;

   return $self;
}


Die Zuweisung will nicht:

Code: (dl )
1
2
3
4
5
6
7
    my ($self) = @_;

   # ...

   $self->{_config}->{$var} = $value;

   # ...


Als Fehler bekomme ich: Reference found where even-sized list expected

Ich habe schon versucht, ein %config als Referenz an _config zu übergeben, aber das klappt irgendwie mit der Zuweisung später nicht (obwohl es wohl die richtige Lösung für das Problem wäre).

Wie kann ich es richtig machen?
renee
 2007-02-14 17:21
#74328 #74328
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Zeig mal bitte etwas mehr Code... In dem hier gezeigten Code-Stück ist an sich kein Fehler...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Lightman
 2007-02-14 17:28
#74329 #74329
User since
2007-01-31
57 Artikel
BenutzerIn
[default_avatar]
Der Konstruktor:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
sub new {
   my ($class, %args) = @_;

   $args{path} = $ENV{HOME} . "/www/" unless defined $args{path};

   my $self = bless {
       _file   => $args{file},
       _path   => $args{path},
       _config => {},
   }, $class;

   return $self;
}


Und hier die Methode:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
sub open_file {
   my ($self) = @_;

   # ...

   while (<CONFIG>) {
       # ... (String-Bearbeitung)

       my ($var, $value) = split(/\s*=\s*/, $_, 2);
       $self->{_config}->{$var} = $value;
   }

   # ...
}


Und der Aufruf in meiner "test.cgi":
Code: (dl )
1
2
3
4
5
6
7
my $config = Configuration->new(file => "config",
                                path => "./");

$config->open_file();
my %hash = $config->get_config();

print $hash{server};


Die Datei wird geladen, aber die Zuweisung klappt nicht. Weshalb print nicht funktioniert (Use of uninitialized value in print). get_config liefert nur _config zurück.
betterworld
 2007-02-14 18:40
#74330 #74330
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
Vielleicht solltest Du noch die Subroutine get_config zeigen?

Und ein ganz verbreiteter Fehler, der aber vielleicht nichts mit dem Problem zu tun hat: Mach vor dem while (<CONFIG>) bitte noch ein local $_;.
Lightman
 2007-02-14 18:43
#74331 #74331
User since
2007-01-31
57 Artikel
BenutzerIn
[default_avatar]
Die get_config-Methode:

Code: (dl )
1
2
3
4
5
sub get_config {
my ($self) = @_;

return $self->{_config};
}


Meinst du:

Code: (dl )
1
2
    local $_;
while (<CONFIG>) {

? Wieso ist das nötig? In meinen Perl-Büchern steht diesbzgl. nichts, bzw. zu der Notwendigkeit.
renee
 2007-02-14 21:47
#74332 #74332
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Mach aus
Code: (dl )
my %hash = $config->get_config();
ein
Code: (dl )
my %hash = %{$config->get_config()};
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
betterworld
 2007-02-14 21:59
#74333 #74333
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
[quote=Lightman,14.02.2007, 17:43]
Code: (dl )
1
2
    local $_;
   while (<CONFIG>) {

? Wieso ist das nötig? In meinen Perl-Büchern steht diesbzgl. nichts, bzw. zu der Notwendigkeit.[/quote]
Genau deswegen sage ich ja "weitverbreiteter Fehler".  Gerade vorgestern habe ich mir mit so etwas wieder in den Fuß geschossen ;-)

Betrachte einfach das folgende Script, dann wirst Du das Problem wahrscheinlich erkennen:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
my @files = ("testfile", "irgendwas");

for (@files) {
  my $lines = count_lines($_);
  print "$_ hat $lines Zeilen.\n"; # Achte genau auf die Ausgabe
}

sub count_lines {
  my $filename = shift;
  open my $F, "<", $filename or die "Kann $filename nicht oeffnen: $!\n";
  my $counter=0;

  # In einem guten Script wuerde an dieser Stelle local $_; stehen

  while (<$F>) {
      ++$counter;
  }
  return $counter;
}

(Wenn man dieses Script ausfuehren moechte, sollte man vorher die Dateien "testfile" und "irgendwas" anlegen.

Es ist ein fuerchterlicher Misszustand, dass so viele Leute davon nichts wissen, sogar wenn sie Buecher ueber Perl schreiben.\n\n

<!--EDIT|betterworld|1172928132-->
dukeofnukem
 2007-02-16 16:36
#74334 #74334
User since
2007-01-15
47 Artikel
BenutzerIn
[default_avatar]
Macht wirklich haufenweise Sinn wenn man endlich mal drüber nachdenkt, vielen Dank!

Gefährliches Völkchen diese magischen Variablen ;)
drum&bass is a state of mind
Lightman
 2007-02-17 19:36
#74335 #74335
User since
2007-01-31
57 Artikel
BenutzerIn
[default_avatar]
So, ich hab noch etwas in meinem Kochbuch geblättert und da wird angegeben, für welche Fälle man local nutzen muss. Darunter auch der von betterworld beschriebene Punkt:
"Sie müssen globalen Variablen einen temporären Wert geben, insbesondere $_." Eigentlich ganz einleuchtend. Ich versuch's mir zu merken. Danke jedenfalls. ;-)

renee's Vorschlag klappt leider nicht, ich bekomme weiterhin ein "Reference found where even-sized list expected". Wenn ich die Zeit finde, versuche ich mich noch etwas mehr in Referenzen einzuarbeiten, vielleicht bekomme ich es dann ja hin.

Danke trotzdem erst einmal.
Lightman
 2007-02-19 15:41
#74336 #74336
User since
2007-01-31
57 Artikel
BenutzerIn
[default_avatar]
Nach etwas rumprobieren habe ich es jetzt doch noch hinbekommen:

Code: (dl )
1
2
3
4
5
sub get_config {
   my ($self) = @_;

   return %{ $self->{_config} };
}


Und der Aufruf der Methode:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
my $config = Configuration->new(file => "config",
                                path => "./");
$config->open_file();

my %hash = $config->get_config();

# Gibt 'mysql' aus...
print $hash{Server} . "\n";

# Klappt auch wunderbar...
$hash{Server} = "test";


Danke noch einmal für eure Hilfe.
<< >> 10 Einträge, 1 Seite



View all threads created 2007-02-14 17:10.