Schrift
[thread]11258[/thread]

Hash by value als Sub-Parameter übergeben

Leser: 1


<< |< 1 2 >| >> 19 Einträge, 2 Seiten
KurtZ
 2008-02-06 19:55
#105654 #105654
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
Hallo

übergibt man mehrere Hashes an ein sub empfiehlt es sich Refs zu übergeben. Wenn man aber im sub eine my Variable nicht ständig deferenzieren möchte, schreibt man letztendlich sowas wie


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???

Beim rumprobieren bin ich nur auf häßliche Sachen wie
Code (perl): (dl )
1
2
3
my %hash1=%{$_[0]};
# oder
my %hash1=%{scalar shift};

gekommen.

Oder Typeglobbing, wo ich aber Aliases erzeuge wo sich Werteveränderungen durchschlagen. Zudem sind die Variablen global statt privat!
Code (perl): (dl )
(*hash1,*hash2)=@_;


Weiß jmd was eleganteres? (Ich hab ja wenig Hoffnung in Perl5 ...aber wer weiß...)

Gruß
Kurt
TMTOWTDYOG (there's more than one way to dig your own grave)
Linuxer
 2008-02-06 20:02
#105656 #105656
User since
2006-01-27
3875 Artikel
HausmeisterIn

user image
Hi,

ich finde

Code (perl): (dl )
1
2
3
sub foo {
  my %hash = %{ shift @_ };
}


nicht wirklich hässlich und das ist auch die Variante, die ich zuletzt immer eingesetzt habe.
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!
KurtZ
 2008-02-06 20:08
#105657 #105657
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
Hi

Linuxer+2008-02-06 19:02:10--
ich finde

Code (perl): (dl )
1
2
3
sub foo {
  my %hash = %{ shift @_ };
}


nicht wirklich hässlich und das ist auch die Variante, die ich zuletzt immer eingesetzt habe.


ich geb dir recht und danke herzlich! :)

Was mich nur verwirrt ist nur, dass es bei meinen Experimenten ohne explizites "@_" nach dem "shift" nicht funktioniert hat ?!?

Also
Code (perl): (dl )
1
2
3
sub foo {
  my %hash = %{ shift };
}
TMTOWTDYOG (there's more than one way to dig your own grave)
Linuxer
 2008-02-06 20:13
#105659 #105659
User since
2006-01-27
3875 Artikel
HausmeisterIn

user image
Perl vermag nicht zu erkennen, dass Du die interne Funktion shift() meinst, und keinen Hash %shift; es meldet in Verbindung mit warnings: "Ambiguous use of %{shift} resolved to %shift ..."

Durch den Zusatz des @_ wird klar, dass in diesem Zusammenhang die Funktion gemeint ist.
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!
KurtZ
 2008-02-06 20:21
#105660 #105660
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
argh ... mea culpa, vor lauter Data Dumping hab ich die Warnings nicht mehr gesehen... [1]

Ja super, dann kann man ja auch noch eleganter schreiben:

Code (perl): (dl )
1
2
3
sub foo {
  my %hash = %{ shift() };
}



DANKE!

Kurt

[1]hmm vielleicht bekomme ich den cperl-mode in emacs ja dazu Warnings farbig anzuzeigen.
TMTOWTDYOG (there's more than one way to dig your own grave)
Struppi
 2008-02-07 12:39
#105678 #105678
User since
2006-02-17
628 Artikel
BenutzerIn
[Homepage]
user image
Also ich persönlich finde das so schöner, auch wenn eine Variabel mehr benutzt wird, aber so ist klarer wieviele Parameter aufgenommen werden:
Code (perl): (dl )
1
2
3
sub routine {
my ($hash_ref1, $hash_ref2) = @_;
my %hash1 = %$hash_ref1;       #umkopieren
KurtZ
 2008-02-08 13:49
#105711 #105711
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
Ich denke es kommt drauf an wieviele Parameter man übergibt und wie groß die Routine ist.
TMTOWTDYOG (there's more than one way to dig your own grave)
Struppi
 2008-02-08 13:53
#105714 #105714
User since
2006-02-17
628 Artikel
BenutzerIn
[Homepage]
user image
Du meinst wieviel Parameter umkopiert werden sollen?
Würd ich sowieso eher vermeiden, aber ich kenne natürlich nicht das Szenario.

Aber wieso sollte die Größe der Funktion eine Rolle spielen?
murphy
 2008-02-08 15:33
#105722 #105722
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
KurtZ+2008-02-06 18:55:13--
[...]
Oder Typeglobbing, wo ich aber Aliases erzeuge wo sich Werteveränderungen durchschlagen.


Das kann allerdings auch ein ziemlicher Vorteil sein, wenn man entweder tatsächlich vor hat, den übergebenen Hash zu verändern oder einfach den Speicher für eine Kopie sparen möchte, weil der Hash recht groß ist.

Quote
Zudem sind die Variablen global statt privat!
[...]


Das Problem des globalen Gültigkeitsbereiches kann man durch den Einsatz von local umgehen:
Code (perl): (dl )
1
2
3
4
5
6
7
sub foobar(\%) {
  local *local_hash = shift;
  # do what you want
}

my %my_hash;
foobar %my_hash;

When C++ is your hammer, every problem looks like your thumb.
sid burn
 2008-02-09 02:31
#105733 #105733
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Man kan im hash auch ein + nutzen. Damit sagt man perl dann das der Inhalt Perl Code ist. Somit geht auch das shift.

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/perl
use warnings;
use strict;

foo({ hallo => 'welt' });

sub foo {
    my %bar = %{+ shift };

    print $bar{hallo}, "\n";

    return;
}


Allerdiengs finde ich alle hier genannten beispiele häßlicher als die Standardmethode des dereferenzierens. Und über lesbarkeit, wartbarkeit und Verständnis brauchen wir gar nicht erst reden. Nicht jeder kennt es, sonst würde dieser Thread ja auch gar nicht existieren.

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.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
<< |< 1 2 >| >> 19 Einträge, 2 Seiten



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