Christoph Pingel: Array Referenz in Perl

Hallo,

Ich will in einer Schleife ein Array füllen, welches ich dann in einem Hash per Referenz "abspeicher". Beim nächsten durchlauf habe ich ja wieder das Array, will dort aber neue Daten einfügen und eine neue Referenz unter einem anderen Key abspeichern. Das wollte ich so machen:

%myhash;

while(irgendwas)
{

#... Datenbankabfrage

my(@array);

#... füllen des Arrays
...
#... ermitteln des richtigen Keys
...

$myhash{$key} = [ @array ];

}

Mein Problem ist jetzt, daß ich nicht weiß, ob nach dem "my" trotzdem noch die alte Referenz gilt oder dort ein neuer Speicherbereich reserviert wird. Wie kann ich das sonst machen, daß garantiert immer ein neuer Speicherbereich reserviert ?

In C++ würde ich jedesmal per "new" ein neues Array anlegen und den Pointer dann speichern, aber wie ist das hier in Perl ?

MFG,
Christoph

  1. Hoi,

    Ich will in einer Schleife ein Array füllen, welches ich dann in
    einem Hash per Referenz "abspeicher". Beim nächsten durchlauf
    habe ich ja wieder das Array, will dort aber neue Daten einfügen
    und eine neue Referenz unter einem anderen Key abspeichern.

    perldoc perlref
    perldoc perldata

    %myhash;

    my %myhash;

    while(irgendwas)
    {

    #... Datenbankabfrage

    my(@array);

    #... füllen des Arrays
    ...
    #... ermitteln des richtigen Keys
    ...

    $myhash{$key} = [ @array ];

    $myhash{$key} = @array;

    }

    Mein Problem ist jetzt, daß ich nicht weiß, ob nach dem "my"
    trotzdem noch die alte Referenz gilt oder dort ein neuer
    Speicherbereich reserviert wird. Wie kann ich das sonst machen,
    daß garantiert immer ein neuer Speicherbereich reserviert ?

    Wenn du eine Variable mit 'my' lexikalisierst, dann wird bei jedem
    Schleifendurchlauf natuerlich eine neue Instanz angelegt. Der
    Gueltigkeitsbereich liegt nur innerhalb der beiden {}.

    Gruesse aus dem schoenen LH,
     c.j.k

    1. use Mosche;

      Mein Problem ist jetzt, daß ich nicht weiß, ob nach dem "my"
      trotzdem noch die alte Referenz gilt oder dort ein neuer
      Speicherbereich reserviert wird. Wie kann ich das sonst machen,
      daß garantiert immer ein neuer Speicherbereich reserviert ?

      Wenn du eine Variable mit 'my' lexikalisierst, dann wird bei jedem
      Schleifendurchlauf natuerlich eine neue Instanz angelegt. Der
      Gueltigkeitsbereich liegt nur innerhalb der beiden {}.

      Nichts für ungut Christian, aber diese Aussage hättest du mal besser qualifizieren sollen, denn sie stimmt zwar (die Aussage über den Gültigkeitsbereich), hat aber IMHO wenig mit der Fragestellung zu tun.

      use Data::Dumper;
      use strict;
      my %myHash;
      foreach (1 .. 3) {
       my $key = 'blah'.$_;
       my @array = ($_++, $_++, $_);
       $myHash{$key} = @array;  # oder (unperformanter ?): [@array]
      }
      print Dumper(%myHash);

      Die Garbage Collection (oder so ähnlich) löscht die Variable nicht, wenn noch Referenzen darauf zeigen, was in diesem Fall zutrifft. So wird zwar jedes Mal eine neue Instanz angelegt, allerdings wird die alte nicht gelöscht, solange deren Referenzzähler nicht gleich 0 ist.

      (Ich freu mich schon darauf, was du jetzt korrigieren wirst :-))

      use Tschoe qw(Matti);

      1. Hi Matti!

        Wenn du eine Variable mit 'my' lexikalisierst, dann wird bei jedem
        Schleifendurchlauf natuerlich eine neue Instanz angelegt. Der
        Gueltigkeitsbereich liegt nur innerhalb der beiden {}.

        Die Garbage Collection (oder so ähnlich) löscht die Variable nicht, wenn noch Referenzen darauf zeigen, was in diesem Fall zutrifft. So wird zwar jedes Mal eine neue Instanz angelegt, allerdings wird die alte nicht gelöscht, solange deren Referenzzähler nicht gleich 0 ist.

        Ich verstehe nicht, wo der Widerspruch zu Christians Aussage ist. Der Fragesteller wollte doch wissen, ob jedes mal "garantiert immer ein neuer Speicherbereich reserviert" wird.

        So long

        --
        "Wenn ich über die steuer- und erbrechtliche Anerkennung von homosexuellen Paaren diskutiere, dann kann ich gleich über Teufelsanbetung diskutieren."
            -- Dr. Edmund Stoiber, 1991

      2. Hoi Matti,

        Nichts für ungut Christian, aber diese Aussage hättest du mal besser
        qualifizieren sollen, denn sie stimmt zwar (die Aussage über den
        Gültigkeitsbereich), hat aber IMHO wenig mit der Fragestellung zu tun.

        Die Frage war, ob in jedem Fall eine neue Instanz der Variablen angelegt wird.
        Das habe ich damit verifiziert. Wo ist dein Problem?

        Die Garbage Collection (oder so ähnlich) löscht die Variable nicht, wenn
        noch Referenzen darauf zeigen, was in diesem Fall zutrifft.

        Hab ich ja auch gar nicht behauptet?

        So wird zwar jedes Mal eine neue Instanz angelegt, allerdings wird die alte
        nicht gelöscht, solange deren Referenzzähler nicht gleich 0 ist.

        Richtig, wo ist der Widerspruch zu dem, was ich gesagt habe?

        (Ich freu mich schon darauf, was du jetzt korrigieren wirst :-))

        Richtiges kann man nicht korrigieren ;-)

        Gruesse aus dem morgendlichen LH,
         c.j.k

  2. Hi!

    %myhash;
    while(irgendwas)
    {
    #... Datenbankabfrage
    my(@array);
    #... füllen des Arrays
    ...
    #... ermitteln des richtigen Keys
    ...
    $myhash{$key} = [ @array ];
    }

    Mein Problem ist jetzt, daß ich nicht weiß, ob nach dem "my" trotzdem noch die alte Referenz gilt oder dort ein neuer Speicherbereich reserviert wird.

    Weiss ich auf Anhieb auch nicht, aber mit [ @array ] legst Du ja in jedem Durchlauf ein neues anonymes Array an, in welches Du dann @array rein-aufloest (aufloesen im Sinne wie Salz in Wasser). Du musst dann nur noch @array=() ausfuehren, um das Array wieder zu leeren.

    Alternative:
    my $array;
    $array = [ ];       # neues leeres anonymes Array anlegen

    ... fuellen

    $myhash{$key} = $array;

    In C++ würde ich jedesmal per "new" ein neues Array anlegen und den Pointer dann speichern, aber wie ist das hier in Perl ?

    Dieses $array = [ ] ist mit dem new vergleichbar.

    So long

    --
    Manchmal habe ich den verdacht, dass meine 'facility-managerin' (aka:putzfrau) mehr ahnung von 'usability' hat als all ihr super-hippen 'web-designer'.
        -- http://www.heise.de/newsticker/foren/go.shtml?msg_id=520197&forum_id=10861&read=1