9
votes

Y a-t-il une telle chose comme une liste dans le contexte scalaire?

my $scalar = ( 1, 2, 3 );  # $scalar gets 3, accidentally

9 commentaires

N'est-ce pas tout simplement "des anges dansant sur la tête d'une épingle"? Si un programmeur croit " $ a = (" foo ', "bar") est l'évaluation d'une liste dans le contexte scalaire, qui évalue à la plupart des éléments, etc. ", quelles sont les conséquences ? Comment cette croyance erronée va-t-elle revenir à la hanter (en dehors de se mettre dans une guerre de flamme avec Brian D Foy)? Avec toutes les autres "idées fausses" communes sur Perl, je peux penser, il existe un simple extrait de code de code - de preuves empiriques - pour prouver un point d'une manière ou d'une autre. Y a-t-il une telle expérience pour cette question? Même un regard sur des internes ou des opcodes?


@mob => Si quelqu'un pense qu'il s'agit d'une liste dans le contexte scalaire, ils peuvent penser qu'avec @a défini comme qw (ABC) dans la liste littérale (11, 22, @a) dans contexte scalaire, la liste élargit ses arguments. Il devient donc (11, 22, 'A', 'B', 'C') Et puis il renvoie le dernier argument, C . Ceci est bien sûr faux, et il renvoie 3 qui est @a dans le contexte scalaire.


Un extrait de code pourrait être: perl -e '@a = qw (a b c); Sous-liste {@_ [0. $ $ # _]} $ x = (11, @a); $ y = liste (11, @a); dire "$ x, $ y" ' qui imprime 3, c


Merci, Eric. Cela efface les choses pour moi (surtout).


@Eric Strom, une liste n'élargise jamais ses opérandes. Les opérandes de l'opérateur sont nécessairement évalués avant l'opérateur lui-même, ils sont donc déjà "étendus" avant que la liste ne les voit. Une liste dans la liste contextuelle est en fait un non-op, il est donc généralement optimisé. Par exemple, perl -mo = concis, -exec -e "mon @s = (@x, @y, @z);"


@mob, ce que j'ai dit à Zaid était tout à l'égard d'éviter "les anges danser sur la tête d'une épingle", en fait. Les personnes qui disent de manière à tort "Il n'y a pas de liste dans le contexte scalaire", causent beaucoup de confusion chez beaucoup de gens, alors nous finissons à faire face aux idées fausses folles ici et sur Perlmonks. Cela a commencé quand j'ai dit à Zaid, il ne devrait pas dire ça. J'ai suggéré qu'il dise "une liste ne peut pas être retourné dans le contexte scalaire", car il évite tout le problème de la tête d'ange.


@ikegami => S'il vous plaît, arrêtez d'être si incroyablement pédant, cela n'aide vraiment pas la conversation. Dans mon commentaire, j'expliquais clairement une erreur qu'un novice pourrait rencontrer. Dites peut-être après avoir lu ceci à Perldata: Les listes font l'interpolation automatique des sublistes. C'est-à-dire que lorsqu'une liste est évaluée, chaque élément de la liste est évalué dans le contexte de la liste et la valeur de la liste résultante est interpolée dans la liste comme si chaque élément individuel était membre de la liste. Ainsi, des tableaux et des hachages perdent leur identité dans une liste ...


@Eric Strom, la façon dont j'ai compris ce que vous avez écrit, il semble que vous disiez qu'il est normal de penser que les listes de contexte scalaire sont élargies car les listes de contexte de liste sont élargies. Exprimant mon désaccord avec cela n'est pas pédant. J'utilise "nit:" quand être penditif. J'étais en train d'être pendante, j'aurais dit "NIT: S / Résultats de son retour du dernier point de la liste littéral / résultats de la liste renvoyant le résultat du dernier opérateur de l'opérateur de liste /"


@ikegami => Bien sûr que c'est faux, c'est tout le point. Et si quelqu'un ne comprenait pas la manière dont le contexte se propage et lu à Perldata? Ensuite, ils pourraient arriver à la conclusion exprimée dans ma réponse à MOB qui a demandé un exemple de mauvaise idée. Il semble au moins 4 autres personnes au moment de la rédaction de cela. Je suppose que tu n'étais pas l'un d'entre eux? Est-ce que le est bien sûr faux et l'exemple de code suivant ne vous suffit pas assez clair? (L'ironie de discuter de la façon dont vous semblez avoir manqué la propagation du contexte dans cette chaîne de commentaires n'est pas perdue sur moi ...)


6 Réponses :


2
votes

Ce n'est pas une liste. Puisque vous cédez à un scalaire, il s'agit de l'opérateur de la virgule - évalue le côté gauche, évalue le côté droit, renvoie le côté droit et résout la gauche-droite. $ scalaire sera 'confus' :)


8 commentaires

@ZAID: Ikegami dit "Formellement, c'est une expression de liste Perl qui renvoie une liste de deux éléments ou un scalaire en fonction du contexte."


Ce qui implique qu'il existe une liste d'une liste dans le contexte scalaire, qui contredit votre réponse.


@Zaid: Non, cela n'implique pas du tout.


Peut-être que je manque quelque chose ici. Soin d'expliquer?


@Zaid: C'est une liste d'expression de la liste qui renvoie une liste [deux éléments] ou un scalaire, selon le contexte. Donc, si le contexte est "attribuer à un scalaire", ce sera un scalaire. Si c'est un contexte de liste, ce sera une liste.


"Opérateur de liste" et "Opérateur de virgule" sont deux noms pour le même opérateur. Contrairement à ce que vous avez dit, ce n'est pas un op binaire, pas même dans le contexte scalaire. (Voir ma réponse.)


@ikegami: Eh bien, c'est ce que je reçois pour poster une réponse sur Perl: P puisque vous avez répondu, cependant, c'est la meilleure réponse.


@Minitech, votre réponse n'est pas mauvaise. En fait, c'est ce que les Documents Perl disent dans un endroit. J'ai commenté pour souligner que les Docs sont parfois trompeurs à ce sujet à ce sujet.



3
votes

Je suis d'accord avec vous et avec perlfaq4 . Pour citer Perldata , qui est probablement le Documentation définitive sur ce point:

Dans un contexte ne nécessitant pas de valeur de la liste, la valeur de ce que semble être une liste littéral est simplement la valeur de l'élément final, comme avec l'opérateur de virgule C.

(mettre l'accent sur le mien).

Cela dit, Ikegami a le droit d'utiliser toute la terminologie qu'il souhaite. Différentes personnes pensent de différentes constructions de langues de différentes conditions, et tant que les résultats finaux sont les mêmes, je ne pense pas que cela compte si leur terminologie diffère de celle de la documentation. (Ce n'est pas une bonne idée d'insister sur la terminologie idiosyncratique dans un forum public, cependant!)


3 commentaires

L'opérateur de liste et l'opérateur de la virgule sont deux noms pour le même opérateur, de sorte que Perlfaq4 n'est donc pas véridique.


Je n'utilise pas cette terminologie, mais elle est très couramment utilisée et c'est ce que Perl utilise. (Voir ma réponse.)


Enfin, c'est ZAID qui insiste sur la terminologie idiosyncratique («non une liste de liste dans le contexte scalaire»). J'ai simplement souligné ce qu'il ne devrait pas utiliser (parce que c'est déroutant et / ou faux), pas ce qu'il devrait utiliser (donc je n'ai utilisé aucune terminologie du tout).



8
votes

Une liste littéral est quelque chose qui est en fait une liste écrite en code, donc (1, 2, 3) code> est une liste littérale, alors que appelant code> par exemple est Une fonction pouvant renvoyer une liste ou un scalaire en fonction du contexte.

dans une ligne comme: p> xxx pré>

code> voit scalaire contexte, donc si ... code> était une liste littérale, alors vous auriez une liste littérale dans le contexte scalaire: p> xxx pré>

mais la liste littérale pas abouti à une liste, car l'opérateur de la virgule qu'il contient le contexte scalaire, qui en résulte ensuite le dernier élément de la liste littérale et jetant les valeurs restantes après les évaluer. P>

en termes de Une fonction, la fonction elle-même voit le contexte qu'on appelle, qui est ensuite propagé à n'importe quelle ligne de cette fonction qui retourne. Donc, vous pouvez avoir une fonction dans le contexte scalaire, la liste ou le contexte annuel, et si la dernière ligne de ce sous-marine est une liste littérale de liste, cette liste littéral verra l'un de ces contextes et se comportera de manière appropriée. P>

Donc, fondamentalement, il s'agit d'une distinction de terminologie, avec Liste Littéral Code> faisant référence à une liste de valeurs séparées par des virgules dans le code source actuel *, et Liste code> faisant référence à une séquence de valeurs placées. sur la pile de Perl. p>

Vous pouvez écrire des sous-programmes avec des valeurs de retour qui se comportent comme des tableaux similaires ou similaires à la liste des littéraux en ce qui concerne le contexte. P>

sub returns_like_array  {my @x = 1..5; return @x}

sub returns_like_list   {my @x = 1..5; return @x[0 .. $#x]}


1 commentaires

Je suis déchiré entre accepter votre réponse et ikegami. Les deux m'ont donné une meilleure compréhension de ce point. Merci!



2
votes

C'est une question de terminologie et de perspective. La terminologie est délicate ici car vous pouvez écrire une liste dans le code source, renvoyer une liste de valeurs ou évaluer quelque chose dans le contexte de la liste .. Et le mot "liste" signifie quelque chose de subtilement différent dans chaque cas!

Techniquement, une liste ne peut pas existent dans le contexte scalaire car Perl (l'interpréteur) ne crée pas une liste de valeurs pour des choses comme ceci: xxx

lorsque vous étiez Pedantic Ceci est précis expliqué comme le comportement de l'opérateur de la virgule dans le contexte scalaire. De même, qw est défini comme renvoyant le dernier élément dans le contexte scalaire, il n'y a pas de liste ici, non plus: xxx

dans ces deux cas (et Pour tout autre exemples d'opérateur que nous pouvions rassembler) ce que nous disons, c'est que l'interprète ne crée pas une liste de valeurs . C'est un détail de mise en œuvre. Il n'y a aucune raison que Perl ne pouvait pas créer une liste de valeurs et jeter tout sauf le dernier; Il choisit simplement de ne pas.

Perl La langue est abstraite. Au niveau de code source ('a', 'b', 'c') est une liste. Vous pouvez utiliser cette liste dans une expression qui impose un contexte scalaire à ce sujet, donc de cette perspective, une liste peut exister dans le contexte scalaire.

à la fin, c'est un choix entre les modèles mentaux de la façon dont [PP] ERL fonctionne. La "liste du contexte scalaire renvoie sa dernière valeur" le modèle est légèrement inexacte mais plus facile à grok. Autant que je sache, il n'y a pas de cas d'angle où il est fonctionnellement incorrect. Le modèle "Il n'y a pas de telle liste de contexte scalaire", le modèle est plus précis, mais plus difficile à travailler, car vous devez prendre en compte le comportement de chaque opérateur dans le contexte scalaire.


0 commentaires

3
votes

Il suffit de demander à Perl! xxx

donc oui, on peut avoir une liste dans le contexte scalaire.

one ne peut pas retourner une liste dans le contexte scalaire. (Eh bien, il est possible de XS, mais le programme s'écrasera, probablement avec une erreur "copie bizarre".)


Il ne peut être autre chose. S'il existait une liste distincte Op et des virgules, il serait impossible de compiler les éléments suivants: xxx

serait-ce que cela entraînerait une liste OU ou une virgule? En réalité, il n'y a pas de telles distinctions, donc oui, il en résulte que OP.


1 commentaires

+1: J'espérais ce genre de réponse "preuve-in-the-pudding"