Silvia: Problem mit Variablenübergabe

Ich habe folgendes (Verständnis)Problem.

#!/usr/bin/perl
use strict;
my %itemSet = GetItem(int($form{'item'}));

sub GetItem {
	my $itemId = shift;
	$itemSet{'item'}{'itemnum'} = $itemId;
	$itemSet{'item'}{'title'} = myHelpers::GetTitle($itemId);
	$itemSet{'item'}{'imageSet'} = myHelpers::GetImageSet($itemId);
	$itemSet{'item'}{'price'} = myHelpers::GetPrice($itemId);
	$itemSet{'item'}{'openGraph'} = myHelpers::SetOpenGraphAttributes( %itemSet );
}

In meiner myHelpers.pm habe ich hier ein Problem:

#!/usr/bin/perl
package myHelpers;
use strict;

[...]

sub SetOpenGraphAttributes {
	my %itemSet = @_;
	my %openGraph;
	$openGraph{'type'} = "website";
	$openGraph{'url'} = $config{'BaseURL'} . "?item=" . $itemSet{'item'}{'itemnum'};
	$openGraph{'title'} = $itemSet{'item'}{'title'};
	$openGraph{'description'} = $itemSet{'item'}{'description'};
	$openGraph{'image'} = $config{'BaseURL'} . $itemSet{'item'}{'imageSet'}{1}{'large'}{'imageFile'};
	return \%openGraph;
}

[...]
1;

Erste verwirrende Sache für mich: Wenn es keinen Wert für $itemSet{'item'}{'imageSet'}{1}{'large'}{'imageFile'} gibt bzw. dieser Schlüssel im Array nicht vorhanden ist, wird dieser Schlüssel angelegt und mit einem leeren Wert belegt. Dazu hatte ich hier ( https://forum.selfhtml.org/self/2017/nov/9/probleme-bei-exists-abfrage-in-einem-hash/1707985#m1707985 ) schon mal nachgefragt und das erklärt bekommen.

Was mich jetzt aber mehr verwirrt: nach dem Rücksprung ins aufrufende Programm ist auch da der Schlüssel $itemSet{'item'}{'imageSet'}{1}{'large'}{'imageFile'} vorhanden, auch wenn es diesen vorher nicht gab. Ich habe ja aber doch das komplette Array %itemSet an die Sub übergeben (und keine Referenz) und dann dort einer lokalen(!) Variablen zugewiesen.

Dann dürfte doch eine Änderung an dieser lokalen Variable %itemSet keine Auswirkungen auf die andere/ originale %itemSet-Variablen haben?

Da ich mir erst mal keinen Rat wusste und davon ausging, dass das wohl doch etwas mit der Namensgleichheit der Variablen zu tun hat, habe ich dann die %itemSet-Variable in der Sub in %itemSetOpenGraph umbenannt my %itemSetOpenGraph = @_; und alle Variablennamen in der Sub dahingehend angepasst.

Aber auch dann stehe ich vor dem selben Phänomen (zumindest für mich :D ), dass die %itemSet-Variable des aufrufenden Programmteils auf einmal einen Schlüssel $itemSet{'item'}{'imageSet'}{1}{'large'}{'imageFile'} hat, den sie vorher nicht hatte.

Wo liegt mein Fehler?

Schon einmal vielen Dank fürs Drüberschauen!

  1. Wo liegt mein Fehler?

    Schon einmal vielen Dank fürs Drüberschauen!

    Mit Verlaub: Das ist unüberschaubar. Sei mal bitte sogut und gib hier mal ein Beispiel der Datenstruktur für eine itemID damit man sehen kann wie die aufgebaut ist. Genauso muss die ja in der Config liegen und da reicht itemID als Schlüssel zum referenzieren -- anstelle einer Fülle von Methoden.

    Wenn schon Methoden, dann nur eine, die, je nach Parameter entweder je itemID den ganzen Hash aus der Config fischt oder einzelne Werte. MfG

    PS: Bei umfangreichen Datenstrukturen immer mit Referenzen arbeiten! Mir scheint, Deine statischen Methoden liefern Kopien und da liegt wahrscheinlich das Prolem.

    1. Mir scheint, Deine statischen Methoden liefern Kopien und da liegt wahrscheinlich das Prolem.

      Ahhh, das könnte sein. Das schau ich mir an.

      Dann sollte ich durch Dereferenzieren eine 'eigenständige' Variable erstellen können?

      Danke!

      1. Mir scheint, Deine statischen Methoden liefern Kopien und da liegt wahrscheinlich das Prolem. Ahhh, das könnte sein. Das schau ich mir an.

        Dann sollte ich durch Dereferenzieren eine 'eigenständige' Variable erstellen können?

        Ja natürlich. Aber guck daß Deine Daten konsisent und zusammen bleiben. Schalte Data::Dumper ein dann siehst Du auch bei umfangreichen Datenstrukturen, wo Du reingreifen musst. Betrachte ein bestimmtes Item als Entity mit einer eindeutigen ID was einen Hash mit beliebigen Attribute=Value Paaren referenziert.

        OOP: Du könntest diesen Hunt einer Entity, der ja auch nur eine Referenz ist, zu einer Instanz einer Klasse machen. Mit dieser Instanz kannst Du dann Methoden aufrufen, die weitere Eigenschaften hinzufügen usw. und letztendlich bestimmte Aktionen ausführen die für eine Response (View) erforderlich sind.

        Dann behältst Du auch die Übersicht. VfG