Schrift
[thread]11258[/thread]

Hash by value als Sub-Parameter übergeben (Seite 2)

Leser: 1


<< |< 1 2 >| >> 19 Einträge, 2 Seiten
murphy
 2008-02-09 03:18
#105736 #105736
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
sid burn+2008-02-09 01:31:11--
Quote
Das Problem des globalen Gültigkeitsbereiches kann man durch den Einsatz von local umgehen:

Dann kann man (und sollte man) auch gleich wieder lexikalische Variablen nehmen.

Sollte: ja, kann: nein -- Designfehler in Perl gibt's eben viele ;-)

Ich wüsste jedenfalls nicht, wie man ohne schwarze Magie und das B-Modul eine lexikalische Variable erzeugen will, die ein Alias auf das Ziel einer Hashreferenz ist.
When C++ is your hammer, every problem looks like your thumb.
betterworld
 2008-02-09 16:53
#105750 #105750
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
KurtZ+2008-02-06 18:55:13--
Code (perl): (dl )
1
2
3
4
5
sub routine {
my ($hash_ref1,$hash_ref2)=@_;
my %hash1=%{$hash_ref1};       #umkopieren
$hash1{key}="wert";                    #wirkt sich nicht auf ursprüngliches Hash aus
}  


$hash_ref1 brauch ich nur einmal ... geht das auch direkter???


Es aendert zwar nichts daran, dass Du $hash_ref1 nur einmal brauchst, aber man koennte das ein klein wenig kuerzer schreiben:
Code (perl): (dl )
1
2
3
4
sub routine {
    my ($hash_ref1,$hash_ref2)=@_;
    my %hash1=(%$hash_ref1, key => 'wert');
}


Wenn es Dich stoert, dass der Hash waehrend der Subroutine doppelt im Speicher liegt, kannst Du ja das hier machen:
Code (perl): (dl )
1
2
3
4
sub routine {
    my ($hash_ref1,$hash_ref2)=@_;
    $hash_ref1={%$hash_ref1, key => 'wert'};
}

Dann musst Du halt nur die späteren Aufrufe von $hash1{key} ändern zu $hash_ref1->{key}

Sachen wie $_[0] wuerde ich auch nicht zu viel verwenden. Sieht irgendwie doof aus und ist unuebersichtlich. Die uebergebenen Variablen immer explizit benannten Variablen zuzuweisen finde ich fuer die meisten Faelle am besten.
KurtZ
 2008-02-09 19:59
#105756 #105756
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
OK,

Schau an, ein neuer Schritt auf der Magierleiter

Code (perl): (dl )
1
2
     
        my %hash1=(%$hash_ref1, key => 'wert');


dürfte gleichwertig sein zu

Code (perl): (dl )
        my %hash1=do { %$hash_ref1, key => 'wert'  };


aber dann verlassen mich meine Zauberkünste, klär mich bitte auf. :)

Gruß
Kurt
TMTOWTDYOG (there's more than one way to dig your own grave)
murphy
 2008-02-10 00:18
#105757 #105757
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
betterworld+2008-02-09 15:53:09--
[...]
Wenn es Dich stoert, dass der Hash waehrend der Subroutine doppelt im Speicher liegt, kannst Du ja das hier machen:
Code (perl): (dl )
1
2
3
4
sub routine {
    my ($hash_ref1,$hash_ref2)=@_;
    $hash_ref1={%$hash_ref1, key => 'wert'};
}

[...]


<haarspalterei>Solange $hash_ref1 nicht die einzige Referenz auf den betreffenden Hash ist, liegen die Daten aber trotzdem zweimal im Speicher.</haarspalterei>
When C++ is your hammer, every problem looks like your thumb.
betterworld
 2008-02-10 02:56
#105759 #105759
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
KurtZ+2008-02-09 18:59:26--
OK,

Schau an, ein neuer Schritt auf der Magierleiter

Code (perl): (dl )
1
2
     
        my %hash1=(%$hash_ref1, key => 'wert');


dürfte gleichwertig sein zu

Code (perl): (dl )
        my %hash1=do { %$hash_ref1, key => 'wert'  };


aber dann verlassen mich meine Zauberkünste, klär mich bitte auf. :)


Hm, wie Du jetzt auf dieses do-Konstrukt kommst, weiß ich nicht. Worueber soll ich Dich aufklaeren? Wie diese Zeile da oben funktioniert? Naja, wenn Du zwei Hashes folgendermaßen bestückst:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
my %hash1 = (
    karl => 'egon',
    key => 'wert1',
);
my %hash2 = (
    karl => 'egon',
    key => 'wert1',
    key => 'wert2',
);

dann wird in dem zweiten Hash der Schlüssel "key" auch nur ein einziges Mal drin sein (ein Schlüssel ist in einem Hash nie doppelt), und es wird der zweite Wert "wert2" genommen. Und die zweite Anweisung kann man halt auch so schreiben:
Code (perl): (dl )
1
2
3
4
my %hash2 = (
    %hash1,
    key => 'wert2',
);

Ist ja irgendwie dasselbe. Und ungefaehr genauso funktioniert das, was ich tagsüber geschrieben habe.
murphy
 2008-02-10 15:41
#105766 #105766
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Ist eigentlich irgendwo dokumentiert, dass beim Bestücken eines Hashes aus einem Listenkontext alle Schlüssel-Wert-Paare sequentiell von vorne nach hinten abgearbeitet werden, dass also
Code (perl): (dl )
my %hash = (k0, v0, k1, v1, ...);

äquivalent zu
Code (perl): (dl )
1
2
3
4
5
6
7
8
my %hash;
{
  my @kv = (k0, v0, k1, v1, ...);
  while (@kv) {
    (my $k, my $v, @kv) = @kv;
    $hash{$k} = $v;
  }
}

ist? Nicht dass man sich darauf verlässt und irgendein Scherzbold kommt auf die Idee bei Perl 5.42 die Reihenfolge umzudrehen, weil nirgends steht, dass es sorum sein muss ;-)
When C++ is your hammer, every problem looks like your thumb.
KurtZ
 2008-02-10 15:54
#105767 #105767
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
KurtZ+2008-02-09 18:59:26--
aber dann verlassen mich meine Zauberkünste, klär mich bitte auf. :)




tatsächlich habe ich 10 min nach dem Posten die nötige Erleuchtung gehabt aber da saß ich schon im Auto...


betterworld+2008-02-10 01:56:37--
Hm, wie Du jetzt auf dieses do-Konstrukt kommst, weiß ich nicht.


wg des blöden -> Scalar Comma Operators

Only Perl can parse Perl, seufz...

PS: zugegeben ich bin Farbenschwach, aber die Farbwahl für URLs in diesem Forum ist etwas unauffällig.
TMTOWTDYOG (there's more than one way to dig your own grave)
KurtZ
 2008-02-11 18:13
#105787 #105787
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
murphy+2008-02-10 14:41:50--
Ist eigentlich irgendwo dokumentiert, dass beim Bestücken eines Hashes aus einem Listenkontext alle Schlüssel-Wert-Paare sequentiell von vorne nach hinten abgearbeitet werden,


Ich habe erstmal gebraucht um deinen Einwand zu verstehen, du befürchtest ein hinterer Key könnte auch von einem vorherliegenden gleichnamigen überschrieben werden.

Ich kenne keine Dokumentation, Spezifikationen sind bei Perl 5 eh zweitrangig zum Status Quo des Interpreters.

Aber ich denke es ist naheliegend davon auszugehen, schließlich müsste die linke Seite in einem ersten Pass erst die Länge der Liste ermitteln. Insbesondere bei Hashes könnte die rechte Liste ja ungradzahlige Länge haben. Andersrum wäre ja unperformant...

ah jetzt ja, im Lamabuch wird "reverse" zum invertieren von hashes beschrieben.
Code: (dl )
%by_name = reverse %by_address;     # Invert the hash

...und gewarnt das dann bei mehrfach vorkommenden Values der letzte gewinnt
(was die Sache in diesem Fall unvorhersagbar macht, weil die Reihenfolge der Keys im rechten Hash nicht definiert ist!)
TMTOWTDYOG (there's more than one way to dig your own grave)
KurtZ
 2008-02-11 20:04
#105794 #105794
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
@murphy:

murphy+2008-02-10 14:41:50--
Code (perl): (dl )
my %hash = (k0, v0, k1, v1, ...);


du hast übrigens eine schöne Begründung für den Einsatz von qw( k0 v0 k1 v1 ) gebracht ... :-)
TMTOWTDYOG (there's more than one way to dig your own grave)
<< |< 1 2 >| >> 19 Einträge, 2 Seiten



View all threads created 2008-02-06 19:55.