7
votes

Trouver le type de données d'une variable scalaire dans Perl

J'ai une fonction qui accepte une entrée de l'utilisateur. L'entrée peut-être un entier, un flotteur ou une chaîne. J'ai trois fonctions surchargées qui doivent être appelées sur la base du type de données des données saisies. Par exemple, si l'utilisateur entre dans un entier (disons 100), la fonction ayant un paramètre entier doit être appelée. Si l'utilisateur entre dans une chaîne (disons "100"), la fonction doit être appelée le paramètre String.

Donc, j'ai besoin de trouver le type de données des données saisies. Avec des expressions régulières, je suis capable de distinguer un entier et un flotteur (car j'ai juste besoin de trouver le type, je préférerais utiliser la bibliothèque fournie sur cpan.org), mais je ne suis pas capable de comprendre comment différencier un entier d'une chaîne. Perl traite "100" et 100 comme la même chose? Y a-t-il un moyen de contourner ce problème?


4 commentaires

Traitement "100" et 100 est généralement considéré comme une caractéristique de Perl. Vous devez expliquer mieux pourquoi c'est un problème. Que devrait-il arriver lorsqu'un utilisateur appelle your_function (100) et comment devrait-il être différent de quand un utilisateur appelle votre_function ("100") ?


Ohk .. Je pensais ne pas entrer dans les détails de cela. Mais puisque la situation demande: je dois appeler certaines fonctions C de l'intérieur de Perl. Les fonctions sont surchargées et présentes dans ma bibliothèque. J'ai donc besoin de trouver le type et d'appeler la version correcte de la fonction explicitement.


Ne tenez pas compte de ma réponse [supprimée]. J'ai mal compris l'intention de la question et je ne me suis pas réalisé que vous parlez de «l'entrée» étant des arguments physiques aux fonctions.


Si l'utilisateur appelle my_function (100), la fonction doit appeler certaines c_int (100) tandis que si l'utilisateur appelle comme my_function ("100"), la fonction doit appeler, dire c_string ("100")


4 Réponses :


11
votes

de perdoc perdata :

Les scalaires ne sont pas nécessairement une chose ou une autre. Il n'y a aucun endroit où déclarer une variable scalaire d'être de type "chaîne", tapez "numéro", tapez "référence" ou autre chose. En raison de la conversion automatique des scalaires, des opérations qui renvoient des scalaires n'ont pas besoin de s'en soucier (et de ne pas s'en soucier de) si leur appelant recherche une chaîne, un nombre ou une référence. Perl est une langue polymorphe contextuelle dont les scalaires peuvent être des chaînes, des chiffres ou des références (qui inclut des objets). Bien que des chaînes et des chiffres soient considérés à peu près la même chose pour presque toutes les fins, les références sont des pointeurs de manière fortement typée et intrinsèque dotée d'une invocation de référence de référence et de destructeurs de référence.

Donc, pour des scalaires entier, vous devrez simplement décider de l'avance sur la manière dont vous voulez les traiter. Perl convertira gaiement d'un numéro à une chaîne ou inversement en fonction du contexte.


1 commentaires

Hmm merci .. donc je ne devrais donc pas perdre mon temps sur cela et régler une autre approche pour y faire face .: D



2
votes
#!perl6

use v6;

multi guess ( Int $a ) { say "got integer: $a" }
multi guess ( Str $a ) { say "got string: $a" }  
multi guess ( Rat $a ) { say "got float: $a" }

guess(3);
guess("3");
guess(3.0);
Cheating, I know...Paul

1 commentaires

super!! Va certainement le donner un essai. Par aucune chance, de telles options ou toute autre alternative avec la version 5 ??



10
votes

Perl ne fait pas une distinction utile entre les nombres et les représentations de cordes de ces chiffres. Votre script ne devrait pas non plus. Vous pouvez écrire du code pour différencier des éléments qui ressemblent à des entiers et de flotteurs, mais le seul moyen de savoir s'il s'agit d'une chaîne est si le scalaire ne ressemble pas à un entier ou à un flotteur.

Voici une simple routine Retournera int code>, rat code> ou str code> pour son argument. Notez que 100 code> et '100' code> sont les deux int code>, mais quelque chose comme 'asdf' code> sera STR code>. p> xxx pré>

puisque vous travaillez sur la cartographie des variables de Perl aux fonctions C, vous pouvez écrire quelque chose comme ceci: P>

sub myfunction {
    if (looks_like_number($_[0]) {
        if ($_[0] =~ /\D/) {C_float($_[0])}
        else               {  C_int($_[0])}
    }
    else {C_string($_[0])}
 }


1 commentaires

Je ne suis pas d'accord avec cela du tout: "Votre script ne doit pas non plus." Ce n'est pas parce qu'une langue ne fait pas que quelque chose n'implique pas que faire cette chose est toujours fausse.



1
votes

Avez-vous envisagé de passer la fonction une référence de hachage avec les touches indiquant quel type de données l'entrée est?

switch ($datatype) {
   case string:
       C_string($input->{$datatype});
   case integer:
       C_integer($input->{$datatype});
   case float:
       C_float($input->{$datatype});
}


0 commentaires