Schrift
[thread]534[/thread]

Unverständliche Typenzuweisung: Skriptanalyse



<< |< 1 2 >| >> 13 Einträge, 2 Seiten
angelsfall
 2005-07-22 12:52
#5313 #5313
User since
2005-07-06
6 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo,

ich habe zu folgendem Problem schon viel gesucht, aber nichts konkretes gefunden: (Ausschnitt aus einem Skript)

Code: (dl )
1
2
my $q = new CGI;
my %$v = %{$q->Vars};


Was mir unverständlich ist, ist die Variablendefinition %$v.
Vars() liefert ja, abhängig vom Kontext, einen Hash (im Hash-Kontext) oder eine Referenz auf einen Hash (im skalaren Kontext), in diesem Fall eine Referenz, da sie ja sofort dereferenziert wird. Wieso ist dann die Variable, der dieser Hash dann zugewiesen wird, kein Hash, sondern sieht wiederum aus wie eine Hash-Dereferenzierung? Das ergibt für mich keinen Sinn, da es, wenn es nochmals dereferenziert wird (was an sich schon eigenartig ist), ja wiederum irgendwo gespeichert werden müsste.
Wäre nett, wenn mir das jemand erklären könnte, funktionieren tut es. Ich weiss nur nicht, wie ;)
Ronnie
 2005-07-22 13:29
#5314 #5314
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Der Trick ist das jemand eine Hashref verwenden will, aber nicht die die $q->Vars liefert, da diese 'tied' ist was zu Problemen in der Anwendung führen kann.

EDIT1: Hatte erst vor kurzem selbst dieses Problem in diesem thread: http://board.perl-community.de/cgi-bin....0;t=535\n\n

<!--EDIT|Ronnie|1122024749-->
angelsfall
 2005-07-22 14:13
#5315 #5315
User since
2005-07-06
6 Artikel
BenutzerIn
[Homepage] [default_avatar]
Danke für die Antwort. Tied heisst, dass es fest daran gebunden ist und nicht verändert werden kann?
Mein eigentliches Problem ist die Variabel %$v. Ich hätte das wenn dann in %v abgespeichert. Ich habe es mal getestet, wenn ich eine Variable mit
Code: (dl )
my %$v;
erstellen will, funktioniert das nicht, der Compiler bricht da ab. Das ist das eigentlich Unverständliche.\n\n

<!--EDIT|angelsfall|1122027239-->
Ronnie
 2005-07-22 14:17
#5316 #5316
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Ich denke es geht nur durch die Zuweisung, da erst ein (Hash)ref erzeugt wird $v und gleich entsprechend zugewiesen als %$v. Tied bedeutet das es sich nicht um einen normalen Hash handelt, sondern um ein Objekt das über spezielle Methoden verfügt und sich deshalb wie ein Hash verhält ( mit Ausnahmen! ). Durch die Zuweisung in dereferenziertem Zustand erhält man ein echtes Hashref.\n\n

<!--EDIT|Ronnie|1122027494-->
angelsfall
 2005-07-22 14:26
#5317 #5317
User since
2005-07-06
6 Artikel
BenutzerIn
[Homepage] [default_avatar]
Also mal ganz genau (für mich Unwissenden ;)):
Code: (dl )
$q->Vars

liefert (in diesem Fall) eine Hashref.
Code: (dl )
%{$q->Vars}

Dereferenziert dies, wir haben also einen Hash.
Einen Hash müsste ich doch in %v speichern.
Irgendwie blicke ich das immer noch nicht ganz (dabei gebe ich mir doch solche Mühe ;)).

/edit: Im weiteren Verlauf wird $v als Referenz auf einen Hash verwendet.\n\n

<!--EDIT|angelsfall|1122028688-->
Ronnie
 2005-07-22 14:38
#5318 #5318
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Ja, bis dahin stimmt es. Würdest du den Hashref zuweisen wollen würdest du das so machen:
Code: (dl )
1
2
my $v = $q->Vars;       # tied, oder
my $v = { $q->Vars }; # untied

Derjenige der deinen Code ursprünglich geschrieben hat dereferenziert jetzt auf beiden Seiten der Zuweisung!
Code: (dl )
1
2
3
my %$v = %{ $q->Vars }; # beidseitige dereferenzierung könnte auch so geschrieben werden:
my $v = {}; # hashref
%$v = %{ $q->Vars }; # zuweisung an hasref!

Das ist nicht nötig (wüsste jedenfalls nicht wozu), aber es führt zu der von dir beschriebenen Syntax.

EDIT: Es würde Sinn machen wenn er einen Hashref nur mit zusätzlichen Schlüssel-/Wert-Paaren füllen wollte, was aber wegen des my auszuschliessen ist.\n\n

<!--EDIT|Ronnie|1122028863-->
esskar
 2005-07-22 14:50
#5319 #5319
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/perl

use strict;
use warnings;
use CGI;

my $q = CGI->new;
my %$v = %{$q->Vars};
^Z
Can't declare hash dereference in my at - line 6, near "$v ="
Execution of - aborted due to compilation errors.


kann nicht gehen!
angelsfall
 2005-07-22 14:55
#5320 #5320
User since
2005-07-06
6 Artikel
BenutzerIn
[Homepage] [default_avatar]
Danke für deine ganzen Bemühungen.
Es will bei mir rein logisch einfach nicht *klick* machen.
Wenn ich etwas dereferenziere (%$v), gibt mir das ja einen Wert wieder (in dem Fall ja einen ganzen Hash). Dieser will doch irgendwo gespeichert werden! Anstelle dessen wird diesem Wert wiederum etwas zugewiesen? Das ist für mich so, als würde man einer Funktion, die man aufruft und die etwas wiedergibt, versuchen, einen Wert zuzuweisen, anstelle ihren Rückgabewert selbst irgendwo zu speichern. Beidseitiges Dereferenzieren ergibt daher gar keinen Sinn. Brrr, dass ist alles unlogisch. Besonders, da es ja funktioniert.

/edit: Ja, esskar, so sah es bei mir auch aus. In dem Skript steht oben noch
Code: (dl )
use strict; no strict 'refs';
.
Hat das was damit zu tun?\n\n

<!--EDIT|angelsfall|1122029872-->
Ronnie
 2005-07-22 14:55
#5321 #5321
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Yip, esskar hat Recht! Das kann so nicht in deinem Code stehen, die doppelte Dereferenzierung geht nicht. Steht da ein my davor?!\n\n

<!--EDIT|Ronnie|1122029784-->
angelsfall
 2005-07-22 15:07
#5322 #5322
User since
2005-07-06
6 Artikel
BenutzerIn
[Homepage] [default_avatar]
Ja.
<< |< 1 2 >| >> 13 Einträge, 2 Seiten



View all threads created 2005-07-22 12:52.