| |||||
| Dernière réponse | ||
|---|---|---|
| Sujet : [Perl] passer des parametres par reference | ||
| alligator421 |
|
|
| Aperçu |
|---|
| Vue Rapide de la discussion |
|---|
| alligator421 |
|
| alligator421 |
|
| Aricoh | tu vas t'y retrouver avec tout ce qu'on a dit dans l'topic ?
bon courage ! :lol: |
| Tentacle |
|
| alligator421 |
|
| Aricoh |
bon, j'ai encore dit une connerie, et après ???
|
| Aricoh |
|
| alligator421 |
|
| Tentacle |
|
| Aricoh | [citation]
Pour le coup des hash, as-tu essaye de faire ca : my ($hash_ref) = @_; [/citation] si @_ contient 1 hash, la syntaxe est correcte. si @_ contient 2 hash, je sais pas sur quoi ton $hash_ref va pointer. |
| Tentacle |
|
| Aricoh |
|
| alligator421 |
|
| Tentacle |
|
| alligator421 | raaaaah :sweat: :lol:
bon si je prends mon truc initial tout a fait general, ca donnerait quoi alors ? sub fonction { my $ref_variable = $_[0]; my $ref_tableau = $_[1]; my $ref_hash = $_[2]; # je veux modifier le hash (au retour de la fonction) ........ } ....... Main : { ... &fonction($a,@b,%c); ... }; tout simplement ? t'es sur ? je crois que ca va rien modifier au retour de la fonction parce que c'est un passage des arguments par valeur et pas par reference. Je sais pas tester maintenant, j'ai pas la machine sous la main. [citation] Pour le coup des hash, as-tu essaye de faire ca : my ($hash_ref) = @_; [/citation] ben j'essaierai tout ce qui a ete mis sur ce topic. mais en fait j'ai deja essaye pleins de trucs mais ca marchait pas trop, quand c 1 hash simple c OK mais hash of arrays, il y a des problemes. [jfdsdjhfuetppo]--Message édité par alligator421--[/jfdsdjhfuetppo] |
| Aricoh | Quand je dis my ($hash) = shift; shift utilisé seul sous-entend shift(@_) |
| Aricoh | $toto = shift(@pouet) signifie que $toto reçoit le 1er élément du tableau @pouet. Celui-ci perd son 1er élément, attention à ça
si ton @pouet contenait 10 éléments, il n'en a plus que 9 après la manip (son indice 0 est l'ancien indice 1) |
| Tentacle |
|
| alligator421 | :lol:
Ah ben justement, c'etait ca la question je crois :D my %hash = %{$_[0]}; il semblerait que ca fasse une copie locale (donc sur la pile) du hash qui est passe avec un pointeur mais avec la copie locale qui pointe sur la meme adresse que le pointeur qui est passe en argument (sauf pour les arrays qui sont contenus, eux sont bien locaux a la fonction)). zut c pas clair ca :lol: bon disons que les adresses memoires des CLES du %hash soient identiques a %{$_[0]} mais pas les arrays a l'interieur. J'aimerais trouver un truc qui dise que %hash soit juste 1 lien symbolique pour %{$_[0]} (juste 1 autre nom quoi) si je retire le my devant le my %hash ... , ca devient juste 1 truc global mais ca m'interesse pas trop Comment je fais avec l'histoire du shift quand je passe PLUSIEURS hash, arrays, etc ... en meme temps ? Ca signifie quoi au juste le shift exactement ? J'aime bien les pointeurs, moa :) [jfdsdjhfuetppo]--Message édité par alligator421--[/jfdsdjhfuetppo] |
| Aricoh | J'utilise pas tt à fait la même syntaxe que toi mais quand tu fais ça dans une fonction :
my %hash = %{$_[0]}; Sauf erreur, tu déclare dans ta routine un hash qui est une copie de celui passé en paramètres ou bien c'est un pointeur ? J'ai peut être pas capté ce que tu voulais dire en fait :sarcastic: :lol: Ce que je sais, c'est que si j'ai un hash à passer en param, je ferais plutôt : my ($hash) = shift; ainsi, pas de copie de hash, juste un pointeur arf |
| alligator421 | Merci a tous les deux pour vos reponses constructives. :jap:
>Tentacle : ok, j'ai bien pris note de tes notations pour "a la C++" mais est ce que ta variable $b qui me parait globale dans ton exemple, existe encore hors de la fonction ? Probalement que oui puisque perl les cree "a la volee" (j'evite les globales au possible, c'est la peste dans les gros scripts). J'essayerai de trouver s'il existe une combine sur base de ton exemple. Il me semble bien que j'avais note qq chose sur www.perldoc.com avec les references $$variable. >Aricoh : Oui, je suis tout a fait d'accord avec ce que tu as dit. Tu as bien expliquer. le @_ va reprendre toutes les references de ce qu'il lui transmis via la fonction, mais il va tout fusionner, sans distinction de ce que tu y mets, variable, hash, arrays ... etc. C'est pour cela que j'avais precise dans ce cas : [citation] keys @{$premier_hash} = @_; %second_hash = {}; # !!!!!!! dans la fonction elle-meme [/citation] Toutes les cles du premier et second hash sont reprises et passees en argument a @_ et le second hash ne sais pas recuperer ses propres cles dans la fonction elle-meme. Donc je reprends mon premier exemple, j'avais deja mis le passage par des pointeur pour le @_ : [citation] sub fonction { my $ma_variable = ${$_[0]}; my @mon_tableau = @{$_[1]}; my %mon_hash = %{$_[2]}; # je veux modifier le hash ........ %{$_[2]} = %mon_hash; } ....... Main : { ... &fonction(\$a,\@b,\%c); ... }; [/citation] >&fonction(\$a,\@b,\%c); j'appelle la fonction avec des pointeurs et comme cela on peut recuperer le @_ ordonne, avec : @_ = ($_[0],$_[1],...); Ce que je veux dire, c'est que ca marche tres bien comme j'ai note mais quand j'ai vu le taux d'utilisation processeur quand on utilise 10 pages de code de fonctions qui tourne dans tous les sens 2 ou 3 hash of arrays en argument avec une bonne trentraine de cles et des arrays de 30 variables c'est :ouch: De plus, meme passe avec des pointeurs dans les arguments de fonctions, il me semble que le perl fait une copie locale quand on force une affectation. sub xxx { my %hash = %{$_[0]}; # ici @_ ne comporte qu'1 seul element et pas tous les keys du hash }; si le hash comporte des cles qui point sur des tableaux et que je modifie ces tableaux comme ceci par exemple : $hash{"numero3"}[3] = $variablequelconque; ou bien push ${$hash{"numero3"}},$variablequelconque; le changement ne se reflete pas PAS TOUJOURS sur %{$_[0]} Je vais essayer de retouver un exemple dans 1 de mes fonctions dans un script ou le changement ne s'effectue pas et je suis oblige a la fin de la fonction de mettre : %{$_[0]} = %hash; pour que ce soit OK au retour de la fonction. On dirait qu'il y a une duplication qui est faite en memoire, pourtant en verifiant les adresses memoires : \$hash == \${$_[0]} quand on les imprime. C'est comme si les cles du hash etaient convenablement gerees quand on en ajoute ou on en retire et cela se repercute sur le hash passe en argument (donc %{$_[0]}) , mais que les arrays (qui sont pointes par les cles) proprement dit ne le sont pas ... >Aricoh, manifestement, si tu as eu un out of memory, la gestion de la memoire s'est effectuee sur la pile et non pas sur le tas pour le passage des arguments de fonction, c'est clair :) |
| Aricoh |
|
| Aricoh |
|
| Tentacle | [citation]il y a certainement bien quelque chose comme dans le c++
genre : void fonction (int & a) { int b = a; b = 5; }; // a = 5 [/citation] Non mais attends si tu fais ca : Sub fonction () { $a = shift @_; $b = $a; $$b = 5; } $test = 3; fonction (\$test); // $test = 5 |
| alligator421 | :D ouh-la je crois que je me suis mal exprime.
>tentacle : non, ce n'est pas imprimer les valeurs des variables, hash, ... etc, qui est problematique, ca, c'est ok. >aricoh : ce que tu montres la, est valable quand on passe les references des keys a la fonction ; mais ils sont passes comme un tableau comme tu le notes bien par @_ ce qui veut dire que si on passe un deuxieme hash, on ne sait pas recuperer le deuxieme, les fonctions du perl passe tous ses arguments dans un tableau mais sans distinguo et idem au retour d'une fonction. keys @{$premier_hash} = @_; %second_hash = {}; !!!!!!! C'est pour ca que je montrais une fonction de type : my $ma_variable = ${$_[0]}; my @mon_tableau = @{$_[1]}; my %mon_hash = %{$_[2]}; ce que je voulais savoir c'est comment se debarrasser du "my" d'affectation dans la fonction quand on recupere les arguments. J'aimerais avoir un "alias" pour %{$_[2]} sans devoir passer par la CREATION d'un hash local. Je ne sais pas comment le perl est implemente (il doit y avoir un constructeur de copie a la facon c++ qq part) mais d'experience (a mes depens) je sais que : sub fonction { my %hash = %{$_[0]}; .... # plusieurs traitement avec le %hash qui est modifie et des keys ajoute ... # %{$_[0]} != %hash avec des hash of arrays ! (je sais pas pq) }; c'est pour ca que je suis oblige (?) de mettre la derniere ligne d'affectation : sub fonction { my $ma_variable = ${$_[0]}; my @mon_tableau = @{$_[1]}; my %mon_hash = %{$_[2]}; ........ %{$_[2]} = %mon_hash; # c indispensable sinon parfois c'est egal, parfois ca ne l'est pas ... } il y a certainement bien quelque chose comme dans le c++ genre : void fonction (int & a) { int b = a; b = 5; }; // a = 5 [jfdsdjhfuetppo]--Message édité par alligator421--[/jfdsdjhfuetppo] |
| Aricoh | Voici un exemple (un peu bête mais bon) :
my %Hash; $Hash{1} = 'un'; $Hash{2} = 'deux'; $Hash{3} = 'trois'; Minable, n'est-ce po ? :sarcastic: Imaginons que tu veuilles rajouter une clé dans ton hash en passant ton hash par référence à une fonction RajouteKey, valà ce que ça donne : sub RajouteKey { my ($toto) = @_; # ou = shift; $toto->{4} = 'quatre'; } Au retour, tu récupères une 4ème clé à ton hash. |
| Tentacle |
|
| alligator421 | J'aimerais pouvoir passer des arguments par reference aux fonctions sans utiliser de variables locales dans la fonction meme .
par exemple habituellement je fais : sub fonction { my $ma_variable = ${$_[0]}; my @mon_tableau = @{$_[1]}; my %mon_hash = %{$_[2]}; # je veux modifier le hash ........ %{$_[2]} = %mon_hash; } ....... Main : { ... &fonction(\$a,\@b,\%c); ... }; Bon alors ca marche parfaitement bien, mais c'est inefficace parce le my %... = %... cree une copie locale donc il reconstruit tout le truc en entierete et quand c'est du hash of arrays c'est lourd en performance (autant utiliser des variables globales alors). Je n'ai pas envie de manipuler les hash avec une notation directe (efficace mais barbare) du style : ${$_[2]}{${$_[0]}} = "coucou"; alors que : $mon_hash{$ma_variable} = "coucou"; c'est si sympathique :) Bref j'aimerais utiliser un "raccourci" sans variable locale pour %{$_[2]} |




