Comme d'autres l'ont noté, les termes "fortement typé" et "faiblement typé" ont donc de nombreuses significations différentes qu'il n'y a pas de réponse unique à votre question. Cependant, depuis que vous avez mentionné spécifiquement Perl dans votre question, permettez-moi d'essayer d'expliquer en quel sens Perl est faiblement typé.
Le point est que, en Perl, il n'y a pas une telle chose comme une "variable de type entier", une "variable de type float", une "variable de chaîne" ou une "variable booléenne". En fait, aussi loin que l'utilisateur peut (généralement) de dire, il n'y a même integer, float, string ou boolean valeurs: tout ce que vous avez sont "scalaires", qui sont toutes ces choses en même temps. Ainsi, vous pouvez, par exemple, écrire:
$foo = "123" + "456"; # $foo = 579
$bar = substr($foo, 2, 1); # $bar = 9
$bar .= " lives"; # $bar = "9 lives"
$foo -= $bar; # $foo = 579 - 9 = 570
Bien sûr, comme vous l'avez remarque, tout cela peut être considéré comme un type de contrainte. Mais le point est que, en Perl, les types sont toujours contraints. En fait, il est assez difficile pour un utilisateur de savoir ce que l'interne "type" d'une variable peut être: à la ligne 2 dans mon exemple ci-dessus, en se demandant si la valeur de $bar
est la chaîne de caractères "9"
ou le nombre 9
est à peu près vide de sens, puisque, pour autant que Perl est concerné, ceux-ci sont la même chose. En effet, il est même possible pour un Perl scalaire à l'interne ont à la fois une chaîne de caractères et une valeur numérique dans le même temps, comme c'est par exemple le cas pour l' $foo
, après la ligne 2 ci-dessus.
Le revers de tout cela est que, depuis Perl variables non typées (ou, plutôt, ne pas exposer leur type interne à l'utilisateur), les opérateurs ne peuvent pas être surchargés de faire des choses différentes pour les différents types d'arguments; vous ne pouvez pas simplement dire "cet opérateur ne X pour les nombres et Y pour cordes", parce que l'opérateur ne peut pas (ne pas) dire quel genre de valeurs de ses arguments.
Ainsi, par exemple, Perl a et les besoins à la fois numérique à l'opérateur d'addition (+
) et un opérateur de concaténation de chaîne (.
): comme vous l'avez vu ci-dessus, il est parfaitement bien pour ajouter des chaînes ("1" + "2" == "3"
) ou pour concaténer des nombres (1 . 2 == 12
). De même, le numérique, les opérateurs de comparaison ==
, !=
, <
, >
, <=
, >=
et <=>
comparer les valeurs numériques de leurs arguments, alors que la chaîne des opérateurs de comparaison eq
, ne
, lt
, gt
, le
, ge
et cmp
de les comparer de manière lexicographique comme des chaînes de caractères. Donc, 2 < 10
, mais 2 gt 10
(mais "02" lt 10
, tandis que l' "02" == 2
). (Vous l'esprit, certaines autres langues, comme le JavaScript, essayez d'adapter Perl-comme le typage faible, tandis que également faire de la surcharge d'opérateur. Cela conduit souvent à la laideur, comme la perte de l'associativité pour +
.)
(La mouche dans la pommade ici, c'est que, pour des raisons historiques, Perl 5 n'ont que quelques cas particuliers, comme les opérateurs logiques bit à bit, dont le comportement dépend de la représentation interne de leurs arguments. Ceux-ci sont généralement considérées comme un ennuyeux défaut de conception, depuis la représentation interne peut changer pour le surprenant raisons, et ainsi de prédire la nature de ces opérateurs dans une situation donnée peut être délicat.)
Tout cela étant dit, on pourrait dire que Perl n' ont-fortes; ils sont tout simplement pas le genre de types que vous pourriez vous attendre. Plus précisément, en plus de la "scalaire" type discuté ci-dessus, Perl dispose également de deux types structurés: "array" et de "hachage". Ceux-ci sont très distinctes de scalaires, au point où Perl variables ont différents signes indiquant leur type ($
pour les scalaires, @
pour les tableaux, %
pour le hachage)1. Il y sont des règles de contrainte entre ces types, de sorte que vous pouvez écrire par exemple, %foo = @bar
, mais beaucoup d'entre eux sont tout à fait avec perte: par exemple, $foo = @bar
affecte la longueur du tableau @bar
de $foo
, pas son contenu. (Aussi, il y a un peu étrange autres types, comme les typeglobs et I/O poignées, que vous ne verrez pas souvent exposés.)
Aussi, un léger point faible dans cette belle conception est l'existence de types de référence, qui sont un type spécial de scalaires (et qui peut être distingué de la normale scalaires, à l'aide de l' ref
opérateur). Il est possible d'utiliser des références comme normal scalaires, mais leur chaîne/valeurs numériques ne sont pas particulièrement utiles, et ils ont tendance à perdre leur référence-ness si vous les modifiez à l'aide de la normale scalaire des opérations. Aussi, toute variable Perl2 peuvent être bless
ed à une classe, la transformant en un objet de cette classe; l'OO système de classe en Perl est un peu orthogonal au type primitif (ou typelessness) système décrit ci-dessus, même si c'est aussi "faible" dans le sens de la suite de la duck-typing paradigme. L'opinion générale est que, si vous trouvez vous-même la vérification de la classe d'un objet en Perl, vous êtes en train de faire quelque chose de mal.
1 en Fait, le sceau indique le type de la valeur en cours d'accès, de sorte que, par exemple, la première scalaire dans le tableau @foo
est notée $foo[0]
. Voir perlfaq4 pour plus de détails.
2 Objets en Perl sont (normalement) accessible par le biais de références, mais ce qui obtient réellement bless
ed est l' (éventuellement anonyme) variable de points de référence. Cependant, la bénédiction est en effet une propriété de la variable, pas de sa valeur, de sorte par exemple que l'affectation de la réelle béni variable à l'autre vous donne juste un peu profonde, sans être bénis copie de celui-ci. Voir perlobj pour plus de détails.