Tobias mit Perl Problemen: deep copy versus shallow copy

Hallo liebe Perl Freunde,

Ich habe ein Problem mit einer Schleife, in der ich eine Umgebungsvariable einlese ($_id):

@all_ids = ();
get "id == *", "links";
while (get_next("links")){
push (@all_ids, $_id);
}

Am Ende steht immer ein und derselbe Wert in meinem Array, weil durch push (@all_ids, $_id); immer nur "shallow copies" in das Array geschoben werden und der letzte gültige Wert von $_id sich dann quasi überall befindet, weil nur Referenzen existieren.

Wie mache ich (und jetzt kommt das Problem) ohne zusätzliche require/use Anweisungen zu gebrauchen, eine "deep copy" von $_id?

Für jede gute Erklärung bin ich sehr dankbar. Ich habe zwar die ein oder andere Perl Seite gefunden, die sich mit deep copies beschäftigt, aber ich verstehe nicht, warum ein so tiefgehendes Konzept immer gleich an Mummutbeispielen mit Hashes und ewig vielen Einträgen erklärt werden muss...

Gruß,
Tobias

  1. Hallo liebe Perl Freunde,

    Ich habe ein Problem mit einer Schleife, in der ich eine Umgebungsvariable einlese ($_id):

    @all_ids = ();
    get "id == *", "links";
    while (get_next("links")){
    push (@all_ids, $_id);
    }

    Am Ende steht immer ein und derselbe Wert in meinem Array, weil durch push (@all_ids, $_id); immer nur "shallow copies" in das Array geschoben werden und der letzte gültige Wert von $_id sich dann quasi überall befindet, weil nur Referenzen existieren.

    Aus deinem Beispile läßt sich nicht erkennen, was für ein Typ $_id ist.
    Du musst beim Push nur einen Datenyp dieser Art erzeugen.

    Wie mache ich (und jetzt kommt das Problem) ohne zusätzliche require/use Anweisungen zu gebrauchen, eine "deep copy" von $_id?

    Was hast du den gegen use? Die Verfügbarkeit von Modulen ist eine der größten Stärken von Perl.

    Für jede gute Erklärung bin ich sehr dankbar. Ich habe zwar die ein oder andere Perl Seite gefunden, die sich mit deep copies beschäftigt, aber ich verstehe nicht, warum ein so tiefgehendes Konzept immer gleich an Mummutbeispielen mit Hashes und ewig vielen Einträgen erklärt werden muss...

    Naja, wenn du einen skalar von einem komplexen Datentyp auf ein Array pushst, dann wird halt nur der Skalar also die Referenz verwendet, wenn du etwas anderes willst musst du es Perl sagen.

    Struppi.

    1. Hallo Struppi,

      @all_ids = ();
      get "id == *", "links";
      while (get_next("links")){
      push (@all_ids, $_id);
      }

      Aus deinem Beispile läßt sich nicht erkennen, was für ein Typ $_id ist.
      Du musst beim Push nur einen Datenyp dieser Art erzeugen.

      $_id ist ein Integer. Lege ich dann einfach einen neuen mit "my $somenew" innerhalb der Schleife an?

      Also:

      @all_ids = ();
      get "id == *", "links";
      while (get_next("links")){
      my $somenew = $_id;
      push (@all_ids, $somenew);
      }

      ?

      Wie mache ich (und jetzt kommt das Problem) ohne zusätzliche require/use Anweisungen zu gebrauchen, eine "deep copy" von $_id?

      Was hast du den gegen use? Die Verfügbarkeit von Modulen ist eine der größten Stärken von Perl.

      Ich weiss. Ich würde ja auch, wenn ich könnte. Aber ich verwende Perl hier als "kastrierte" Version, ohne Möglichkeit für require/use. Deshalb muss es ohne gehen.

      Naja, wenn du einen skalar von einem komplexen Datentyp auf ein Array pushst, dann wird halt nur der Skalar also die Referenz verwendet, wenn du etwas anderes willst musst du es Perl sagen.

      Deswegen frage ich ja hier :-)

      Gruß,
      Tobias

      1. Aus deinem Beispile läßt sich nicht erkennen, was für ein Typ $_id ist.
        Du musst beim Push nur einen Datenyp dieser Art erzeugen.

        $_id ist ein Integer. Lege ich dann einfach einen neuen mit "my $somenew" innerhalb der Schleife an?

        Wo denn?

        Also:

        @all_ids = ();
        get "id == *", "links";

        Was ist get? ich kenne get nur aus dem Packet LWP::simple
        und wo ist die Variabel $_id?

        while (get_next("links")){
        my $somenew = $_id;
        push (@all_ids, $somenew);
        }

        ?

        Wenn $_id wirklich ein integer ist:

        my ($_id, @all_ids);

        for $_id (0..10)
        {
         push @all_ids, $_id;
        }

        print join "\n", @all_ids;

        Dann hat das Array auch 11 verschiedenen Werte.

        D.H. dein $_id ist ein komplexer Wert oder einen Referenz.
        Im ersten Fall musst du eine Kopie erzeugen im zweiten dereferenzieren.

        aber wie gesagt aus deinem Codeschnipsel geht nichts hervor um dir helfen zu können, da $_id dort nirgendwo definiert wierd.

        Struppi.