Perl sous-Routine de Prototypage — La bonne façon de le faire
J'ai une sous-routine appelée debug
- je utiliser dans mon code. Fondamentalement, ça me permet de voir ce qu'il se passe, etc.
sub debug {
my $message = shift;
my $messageLevel = shift;
our $debugLevel;
$messageLevel = 1 if not defined $messageLevel;
return if $messageLevel > $debugLevel;
my $printMessage = " " x $messageLevel . "DEBUG: $message\n";
print STDERR $printMessage;
return $printMessage;
}
Je veux prototype, donc je peux faire des choses comme ceci:
debug "Here I am! And the value of foo is $foo";
ou
debug "I am in subroutine foo", 3;
En même temps, j'aime mettre des sous-routine définitions dans le fond de mon programme, de sorte que vous n'avez pas à wade 1/2-chemin à travers le code à trouver de la viande du programme.
J'aimerais faire ceci:
sub debug($;$); #Prototype debug subroutine
/Here goes the main program code/
sub debug { #The entire subroutine goes here
/Here goes the debug subroutine code/
}
Cependant, je reçois un message d'avertissement lorsque je fais ceci:
Prototype mismatch: sub main::debug ($;$) vs none at foo.pl line 249.
Donc, je suis coincé mettre la définition du prototype dans les deux endroits. Quelle est la bonne façon de faire quelque chose comme cela?
RÉPONSE
Arrêter! Module de temps. – Chris Lutz
Un module? Tu veux dire créer un fichier séparé? Qui ajoute un peu de complication, sans résoudre le problème que j'essaie de résoudre: la Suppression de la nécessité pour les parenthèses autour de ce sous-programme particulier.
notre $debugLevel; ne devrait pas être dans le sous-corps de toute façon, mais je suis d'accord avec Chris sur ce. – Sinan Ünür il y a 3 heures
La our $debugLevel
n'a pas à être là, dans ce cas, mais si j'ai défini une classe, et je veux utiliser cette sous-routine dans ma classe à des fins de débogage, j'en ai besoin. Je peux le mettre dans ma classe comme ::debug
Étonnamment, Bien plus que tout ce que vous avez toujours voulu savoir sur les prototypes en Perl ne traite pas de cela, mais je crois que vous ne pouvez pas éviter d'écrire le prototype dans les deux endroits.
J'espérais un moyen facile de l'éviter. Il y a un moyen comme Eric Strom a montré. Malheureusement, c'est plus que mon debug
routine.
J'ai l'habitude d'utiliser des prototypes, mais j'ai pris l'habitude de ne pas écrire des déclarations distinctes pour les sous-routines et à l'aide de parenthèses sur tous les appels: debug("je suis dans la fonction toto", 3);. Il a été suggéré que les prototypes ne sont pas vraiment une bonne idée. TMTOWTDI – Keith Thompson 3 heures
Sauf que moi j'ai tendance à faire:
debug (qq(The value of Foo is "$foo"), 3);
qui peuvent être moins clair lors de la lecture, et peut être une douleur à type de. Chaque fois que vous double-up parenthese, vous êtes d'avoir des ennuis. La dernière chose que je veux faire, c'est de débogage mes instructions de débogage.
Pourquoi voulez-vous prototypes? Voir cette question Comment passer des paramètres facultatifs à une fonction Perl – TLP
Oui, il ya beaucoup de problèmes avec le prototypage. Le principal problème est qu'il n'a tout simplement pas faire ce que les gens pensent qu'il doit faire: Déclarer les types de variables pour les paramètres que vous passez à votre fonction.
Ce n'est pas la raison pour laquelle je suis en utilisant le prototypage ici.
J'utilise rarement des prototypes. En fait, c'est probablement le seul cas dans l'ensemble de mon code où je ne.
our $debugLevel;
ne devrait pas être dans le sous-corps de toute façon, mais je suis d'accord avec Chris sur ce.Étonnamment, perlmonks.org/?node_id=861966 n'a pas d'adresse, mais je crois que vous ne pouvez pas éviter d'écrire le prototype dans les deux endroits.
J'ai l'habitude d'utiliser des prototypes, mais j'ai pris l'habitude de pas rédaction des déclarations distinctes pour les sous-routines et à l'aide de parenthèses sur tous les appels:
debug("I am in subroutine foo", 3);
. Il a été suggéré que les prototypes ne sont pas vraiment une bonne idée. TMTOWTDIPourquoi voulez-vous prototypes? Voir cette récente de la question stackoverflow.com/q/8124138/725418
OriginalL'auteur David W. | 2011-11-14
Vous devez vous connecter pour publier un commentaire.
Simplement se débarrasser de prototypes en tout:
Sauf que dans ce cas, je suis à l'aide de prototypes pour son usage prévu: me permettre d'utiliser un sous-programme sans parenthèses comme vous le feriez avec des fonctions intégrées. Ce que vous ne devriez pas utiliser des prototypes pour est pour la vérification de type.
W - qui est tout simplement faux. Il n'est pas un prototype qui rend les parenthèses en option.
la foule est correct. La chose qui rend les parenthèses facultatif est la déclaration que
debug
est un sous-programme.Merde. J'ai toujours pensé que vous deviez utiliser des prototypes pour éliminer les parenthèses.
OriginalL'auteur Ted Hopp
Le prototype est attaché à la coderef et pas le nom, afin que lorsque vous remplacez la coderef avec la nouvelle déclaration, vous clarifiez le prototype. Vous pouvez éviter d'avoir à croiser et match de prototypes avec une fonction d'assistance:
install
est juste un wrapper autour deScalar::Util
'sset_prototype
fonction, ce qui vous permet de modifier le prototype d'une coderef fois qu'il est créé.Prototypes peuvent être très utiles, mais lors de l'utilisation de l'scalaire prototype, demandez-vous toujours si c'est vraiment ce que vous avez prévu. Parce que le
($;$)
prototype indique à perl de débogage "est une fonction qui peut prendre un ou deux arguments, chacun avec un contexte scalaire imposées sur le site d'appel".La peu sur le contexte est là que les gens généralement de trébucher, parce que si vous essayez de faire ceci:
Puis
@array
obtient vu dans un contexte scalaire, et devient2
. Donc, l'appel devientdebug 2;
plutôt quedebug 'one', 'two';
que vous avez prévu.Ouais, je connais les limites de prototypage. Dans ce cas, je l'utilise comme à peu près prévu. Je veux être en mesure de taper
debug "Some statement";
et peut-être fixer un niveau de débogage commedebug "Some statement", 2;
sans se soucier de parenthèses. La fonction d'assistance est intéressant, mais c'est encore plus long que mon petit debug sous-routine. Pourtant, je l'aime bien que je vais probablement faire comme je l'ai fait avant.Oui, j'ai à propos de ce particulier petit problème avec
debug @array
. Le problème c'est que je veux inclure parfois un niveau de débogage, mais pas nécessairement. Si je passe dans @tableau, je ne sais pas si c'est un tableau, ou un tableau avec un niveau de débogage sur la fin. Je sais ce que je passe à la routine être un scalaire.Juste assez. Les policiers vont tirer downvotes sans avertissement si cet avertissement n'est-il pas à propos de quoi que ce soit concernant prototypes. En fait, je pense que j'ai été touché par l'un tout en tapant...
+1 pour la mention de
Scalar::Util 'set_prototype'
. C'est la clé pour un problème que j'ai, qui m'amènent à cette SORTE de post. 🙂OriginalL'auteur Eric Strom
Si je suis bien comprendre, vous voulez prototype et predeclare de sorte que vous pouvez utiliser la fonction (prototype et braceless) dans le même fichier. C'est ce que le
subs
pragma est pour.Par exemple, ce code fonctionne correctement:
non, tout ce qu'il faut c'est être predeclared. les prototypes de la force de contexte ou d'autres usages spécifiques de listes après la fonction. Pour plus d'informations, voir [
perldoc perlsub
], "le but de cette fonctionnalité est principalement pour vous permettre de définir des sous-routines qui fonctionnent comme des fonctions intégrées"(perldoc.perl.org/perlsub.html#Prototypes)un bon exemple est si vous avez besoin d'une fonction pour prendre deux tableaux distincts ET de ne PAS les aplatir en une seule liste, comme
push
. La plupart du temps on pourrait faire ceci par le fait d'avoir la prise de fonction tableau des références plutôt que des tableaux, mais si vous voulez avoir une interface épurée, puis les prototypes sont la réponse. Il est rarement besoin d'eux.OriginalL'auteur Joel Berger
Vous devez déclarer le même prototype lorsque vous définissez votre sous-routine:
OriginalL'auteur dlamotte
Voici comment le faire:
OriginalL'auteur Sam