Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Comportement de passage de paramètres étonnant

2 réponses
Avatar
Aurelien
Bonjour

Je suis confronté à un comportement étrange lors de passage de
paramètres à une fonction Perl.

Voici une simple méthode et un appel qui y est fait :

__CODE__

20:sub amount {
21: my $self = shift;
22: if (@_) {
23: $_[0] =~ m/^\d+(\.\d{2})?([A-Z]{3})?$/
24: or croak("Amount should be like ...");
25: $self->{AMOUNT} = $_[0];
26: }
27: return $self->{AMOUNT};
28:}

#--
...
#--

10: if ($amount =~ m/^(\d+(\.\d{2})?)([A-Z]{3})$/) {
11: $self->amount($1);
12: $self->currency($3);
13: }

__END__

Et j'ai un comportement très étrange concernant le paramètre $1.
A ma connaissance, ce style de passage doit se faire par valeur.

- ligne 10 et 11: $1 est bien affecté par la regexp et l'appel se fait
normalement.
- ligne 21: Dans amount(), la valeur est bonne au début ($_[0] est
correcte).
- ligne 23: Puis, la regexp de amount() est effectuée, elle positionne
elle aussi $1.
- ligne 24: La valeur de $_[0], qui aurait du être une copie de la
valeur de $1 au moment de l'appel ligne 11, devient la valeur de $1 de
la regexp qui vient d'être exécutée ligne 23.

Je ne comprends pas pourquoi ?
Est-ce que quelqu'un peut m'éclairer ?

Aurélien

2 réponses

Avatar
Paul Gaborit
À (at) Mon, 18 Oct 2004 11:48:35 +0200,
Aurelien écrivait (wrote):
A ma connaissance, ce style de passage doit se faire par valeur.


Le passage des paramètres en Perl se fait par référence. Exemple :

sub test {
$_[0]++;
}

my $a = 1;
test($a);
warn "$an";

qui affichera '2' !

C'est documenté au tout début de 'perlsub' :

Tous les arguments passés à la routine se retrouvent dans le tableau
C<@_>. Ainsi, si vous appelez une fonction avec deux arguments, ceux-ci
seront stockés dans C<$_[0]> et C<$_[1]>. Le tableau C<@_> est un
tableau local, mais ses éléments sont des alias pour les véritables
paramètres scalaires. En particulier, si un élément C<$_[0]> est mis à
jour, l'argument correspondant est mis à jour (ou bien une erreur se
produit s'il n'est pas modifiable).

Dans votre cas, c'est l'inverse qui se passe. Vous mettez à jour $1 (via
l'application d'une nouvelle regexp) et $_[0] qui est un alias de $1 est donc
mis à jour lui aussi.

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>

Avatar
Jack
Le 18/10/2004 11:48, :

Bonjour

Je suis confronté à un comportement étrange lors de passage de
paramètres à une fonction Perl.

Voici une simple méthode et un appel qui y est fait :

__CODE__

20:sub amount {
21: my $self = shift;
22: if (@_) {
23: $_[0] =~ m/^d+(.d{2})?([A-Z]{3})?$/
24: or croak("Amount should be like ...");
25: $self->{AMOUNT} = $_[0];
26: }
27: return $self->{AMOUNT};
28:}

#--
...
#--

10: if ($amount =~ m/^(d+(.d{2})?)([A-Z]{3})$/) {
11: $self->amount($1);
12: $self->currency($3);
13: }

__END__

Et j'ai un comportement très étrange concernant le paramètre $1.
A ma connaissance, ce style de passage doit se faire par valeur.

- ligne 10 et 11: $1 est bien affecté par la regexp et l'appel se fait
normalement.
- ligne 21: Dans amount(), la valeur est bonne au début ($_[0] est
correcte).
- ligne 23: Puis, la regexp de amount() est effectuée, elle positionne
elle aussi $1.
- ligne 24: La valeur de $_[0], qui aurait du être une copie de la
valeur de $1 au moment de l'appel ligne 11, devient la valeur de $1 de
la regexp qui vient d'être exécutée ligne 23.

Je ne comprends pas pourquoi ?
Est-ce que quelqu'un peut m'éclairer ?

Aurélien


Avez vous essayer de stoker et utiliser le résultats $1 dans une autre
variable pour voir?