Question

Une affectation de liste dans un contexte scalaire renvoie le nombre d'éléments sur le côté droit:

scalar(my ($hello, $there, $world) = (7,8)); #evaluates to 2

Pourquoi faut-il évaluer le côté droit et produire 2, au lieu de la liste redéfinie en cours d'évaluation et de retour 3?

Pour moi, il semble que $hello obtient 7, $there obtient 8 et $world obtient undef, alors cette liste est évaluée dans un contexte scalaire, ce qui se traduirait par 3, car c'est le nombre d'éléments dans la liste ($hello $there $world) . Il me semble bizarre de ce contexte affecte la partie de l'expression évaluée est renvoyée:

my $greeting = (($hello, $there, $world) = (7,8)); #2

my @greeting = (($hello, $there, $world) = (7,8));
my $greeting_length = @greeting; #3
Était-ce utile?

La solution

Il est documenté pour compter les éléments à droite dans perlop (le dernier phrase dans la section opérateurs d'affectation):

De même, une affectation de liste dans un contexte de liste génère la liste des lvalues ??affectés, et une affectation de liste dans un contexte scalaire renvoie le nombre d'éléments produits par l'expression du côté de la main droite de l'affectation.

La raison pour laquelle cela fonctionne comme ça est que vous pouvez écrire des choses comme ceci:

while (my ($key, $value) = each %hash) { ... }

Si elle a compté le nombre d'éléments sur le côté gauche de l'affectation, ce serait une boucle infinie.

Si vous pensez à ce sujet, le nombre d'éléments sur le côté gauche est soit le même que sur le côté droit ou il est une constante (quand vous affectez à une liste de scalaires). Dans le premier cas, il ne fait aucune différence de quel côté vous comptez, et dans le second cas, en comptant le côté droit est plus utile.

D'autre part, dans un contexte de liste l'opérateur d'affectation retourne la liste de gauche, parce que ce plus utile. Si vous l'utilisez dans un contexte qui modifie les éléments de la liste, vous souhaitez modifier les variables qui viennent d'être affectés.

Re: votre commentaire Dans votre exemple, (7,8) est une liste à deux éléments, ce qui explique pourquoi le rendement de l'opérateur d'affectation 2. Lorsque vous attribuez une liste plus courte à une liste plus longue de scalaires, le droit côté est pas « rembourré » avec undef avant que la cession se produit. Au lieu de cela, toutes les variables qui n'ont une valeur qui leur est associée dans la liste de droite sont remis à leur valeur par défaut. Pour une variable scalaire, qui est undef. Pour les tableaux, c'est un tableau vide. Pour hash, c'est un hachage vide.

Autres conseils

Il me semble bizarre que les effets de contexte qui est evalué:

Il ne fonctionne pas. Les deux parties (opérandes) de l'opérateur d'affectation de liste évalués, et si l'affectation de la liste est évaluée dans un contexte scalaire ou un contexte de liste ne porte pas atteinte à l'évaluation des opérandes que ce soit.

Si une affectation de liste est évaluée dans un contexte de contexte scalaire ou une liste ne concerne que la valeur qu'elle renvoie.

J'ai déjà créé Scalar vs liste de l'opérateur d'affectation, qui tente de préciser les différences entre les deux opérateurs d'affectation et comment ils se comportent dans un contexte scalaire et la liste.

Pourquoi faut-il évaluer le côté droit et produire 2, au lieu de la liste redéfinie en cours d'évaluation et de retour 3?

Parce que ce que la définition du langage dit qu'il doit faire, parce que ce Larry Wall a décidé qu'il devrait faire.

Pour moi, il semble que $ bonjour obtient 7, il obtient 8 $, et $ monde obtient FNUD, alors cette liste est évaluée dans un contexte scalaire

Non, Perl ne fonctionne pas de cette façon. Vous assumez ce contexte scalaire est juste une conversion du résultat qui aurait été obtenu dans un contexte de liste à un scalaire en comptant le nombre d'éléments dans le résultat de la liste, mais qui est tout simplement pas juste ... un moyen de contexte scalaire une opération (dans cette attribution de cas) devrait produire un résultat scalaire, et il y a souvent des résultats scalaires qui sont plus utiles que juste le nombre d'éléments dans le résultat contextuel de la liste, et qui varie d'un opérateur à ... vous devez vérifier la documentation pour ce produit scalaire; ce n'est pas uniforme. Pour l'affectation de la liste, la valeur scalaire est le nombre d'éléments sur le côté droit, car c'est beaucoup plus utile que le nombre de récepteurs, ce qui est constant. par exemple, if (($a, $b) = $s =~ /$re/) est vrai si le match a produit des résultats, par opposition à être toujours vrai, car il y a deux récepteurs.

Il me semble bizarre de ce contexte affecte la partie de l'évaluation expression est renvoyée

Il y a beaucoup plus étranges choses en Perl. Ce sentiment d'étrangeté provient d'un décalage entre les modèles ... dans ce cas, vos attentes et votre orthogonalité de conviction que « contexte scalaire » est un opérateur sur les listes, par rapport à la conception pragmatique de perl et la réalité que « contexte scalaire » établit un contexte qui détermine le résultat à produire. Notez que vous pouvez écrire vos propres fonctions qui produisent résultats complètement différents en fonction du contexte de l'appel.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top