Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]11937[/thread]

Referenzen Problem : sehr seltsam

Leser: 1


<< >> 8 Einträge, 1 Seite
marky
 2008-05-29 20:34
#110462 #110462
User since
2003-08-15
215 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo,

mir ist schon lange ein Problem mit Referenzen aufgefallen, dass bisher aber nicht sehr gestört hat - jetzt kann ich das verhalten aber nicht gebrauchen und geht um die Prüfung von Werten innerhalb der Referenz.

Wenn ich zb.

if ( exists ( $SESSION->{'cartproducts'}->[0]->{'id'} ) ) {

mache und der Wert nicht vorhanden ist, dann habe ich nachher den Strang plötzlich vorhanden, per Dump dann

VAR1 = {
'cartproducts' => [
{}
],

das ist sehr ätzend, weil beim Durchlaufen, dann ein Element rauskommt, obwohl keines da ist, ich habe schon alles mögliche versucht, aber es nicht hinbekommen, dass genau das nicht passiert.

Hat da jemand eine Idee und kann mir mal erklären, warum das so ist, ich finde ich das zumindest sehr unlogisch.
murphy
 2008-05-29 21:05
#110463 #110463
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Dieses Verhalten wird auch als "Autovivification" bezeichnet und ist in Perl ein ausdrücklich erwünschtes Feature.

Umgehen kann man das nur, indem man explizit prüft, ob jedes Element des Pfades zu dem gewünschten Datenstrukturelement exisitert, also zum Beispiel
Code (perl): (dl )
1
2
3
4
5
6
7
8
if (
  defined($SESSION) &&
  exists($SESSION->{cartproducts}) &&
  exists($SESSION->{cartproducts}->[0]) &&
  exists($SESSION->{cartproducts}->[0]->{id})
) {
  [...]
}

statt
Code (perl): (dl )
1
2
3
if (exists($SESSION->{cartproducts}->[0]->{id})) {
  [...]
}

When C++ is your hammer, every problem looks like your thumb.
moritz
 2008-05-29 21:31
#110465 #110465
User since
2007-05-11
923 Artikel
HausmeisterIn
[Homepage]
user image
Oder man kann das ganze mit CPAN:Data::Diver umgehen.
marky
 2008-05-29 21:40
#110466 #110466
User since
2003-08-15
215 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo,

das ist nicht was ich meine, das ist ja nur das Feature, wenn einer Struktur einen Wert zuweise - ich weise aber keinen Wert zu, sondern prüfe nur, ob es ein Element gibt - das ist keine Zuweisung.

Ich habs mittlerweile auch gefunden, es war noch eine Zeile übrig - die mir durch die Lappen gegangen ist, da war noch eine Zuweisung mit einem falschen Index, deswegen, hat er immer ein leeres Element angelegt.

Wenn es mal fertig ist, ist das super - ich stelle gerade das Session-Management unseres Shops auf Datenstrukturen mit Storable um, das ist mal richtig genial - schnell und unendlich flexibel - aber bei der Umstellung von 10.000 Zeilen leicht unübersichtlich. Viel geht zwar mit suchen und ersetzen, aber anscheindend doch nicht alles :-(

Trotzdem, danke ...
marky
 2008-05-29 21:47
#110467 #110467
User since
2003-08-15
215 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo,

so habe ich das letzte Rätsel noch gelöst, wenn man per slice alle Elemente aus

$SESSION->{cartproducts}->[]

gelöscht hat, bleibt das Array trotzdem leer zurück. Dh. man muss das von Hand löschen, wenn nichts mehr drin ist

unless ( $SESSION->{'cartproducts'}->[0]->{'id'} > 0 ) {

delete ( $SESSION->{'cartproducts'} ) ;
}

das der Strang wirkich komplett verschwindet. Und die Abfrage

$#{$SESSION->{'cartproducts'}}

auch wirklich -1 gibt. Da muss ja echt aufpassen :-)

Danke für die Denkanstösse, manchmal braucht man einfach einen kleinen Tritt.
Linuxer
 2008-05-29 21:53
#110468 #110468
User since
2006-01-27
3890 Artikel
HausmeisterIn

user image
marky+2008-05-29 19:40:17--
Hallo,

das ist nicht was ich meine, das ist ja nur das Feature, wenn einer Struktur einen Wert zuweise - ich weise aber keinen Wert zu, sondern prüfe nur, ob es ein Element gibt - das ist keine Zuweisung.


Hi, das Feature greift auch ohne Zuweisung:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# perl
my %hash;

if ( $hash{aa}->{bb}->{cc} ) {
print "yo\n";
}
else {
print "no\n";
}

use Data::Dumper;
print Dumper \%hash;

^D
no
$VAR1 = {
'aa' => {
'bb' => {}
}
};

#
meine Beiträge: I.d.R. alle Angaben ohne Gewähr und auf Linux abgestimmt!
Die Sprache heisst Perl, nicht PERL. - Bitte Crossposts als solche kenntlich machen!
marky
 2008-05-29 22:00
#110469 #110469
User since
2003-08-15
215 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hmm, bei mir nicht mehr. Komisch.
sid burn
 2008-05-30 01:50
#110470 #110470
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Öhm ein

Code: (dl )
if ( exists $SESSION->{foo}{bar}{baz} ) { ... } 


enthält automatisch auch eine Zuweisung...

Wenn mämlich der eintrag "foo" in der ersten ebene nicht existiert dann erstellt du mit "$SESSION->{foo}{bar}..." bereits das element "foo" als Hasheintrag in der erste ebene. Jeder undefinierte Wert in Perl wird wenn du ihn derenferzierst automatisch den Typ zugeordnet so wie du auf ihn zugreift.

Deswegen gehen ja auch sachen wie.

Code: (dl )
push @{$irgendwas->{werte}}, $wert

Auch wenn du vorher nirgendswo ein
Code: (dl )
$irgendwas->{werte} = [];

geschrieben hast. In diesem Fall wird dann der Eintrag werte beim ersten zugriff auch automatisch erstellt und es wird automatisch eine Arrayreferenz daraus gemacht.

Und da du letztendlich direkt auf "->{foo}{bar}{baz}" zugreifst wird automatisch foo erstellt, damit dieses wiederum als hshref dereferenziert werden kann damit dort ein bar erstellt wird. Und dann wird erst gebrüft ob auf dieser ebene ein "baz" existiert.

Wenn dann musst du es so machen wie "murphy" sagte.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
<< >> 8 Einträge, 1 Seite



View all threads created 2008-05-29 20:34.