2017-10-11 6 views
2

Est-il possible en Perl de déclarer un sous-programme tel que le script ne compilera pas si les paramètres ne lui sont pas transmis lorsqu'il est appelé?Comment avoir un sous-programme avec les paramètres requis?

+2

Comment pouvez-vous dire à la compilation si 'f (@a)' passe n'importe quel paramètre à 'f' ou non? – ikegami

+0

Il est théoriquement possible de faire une sorte de vérification à la compilation avec Devel :: CallChecker ou B :: CallChecker, mais cela nécessite de bien connaître les internes de Perl et de disposer de nombreux modes de défaillance. Par exemple. cela ne fonctionnera pas avec les méthodes, seulement avec certains appels de sous-programme. Cela ne fonctionnera pas si des arguments sont évalués dans le contexte de la liste. À la base, Perl est un langage dynamique. Sous-processus Listes de taille variable, pas de tuples d'argument de taille fixe. Je suis simplement content que la langue soit assez statique pour détecter des sous-marins et des variables inconnus, contrairement aux langages plus dynamiques comme Python. – amon

+0

Qu'en est-il de la PPR? – simbabque

Répondre

1

Je pense que ce genre de chose est sur le mieux que vous pouvez faire actuellement:

#!/usr/local/bin/perl -w 
use strict; 
require 5.020; 
use warnings; 
use feature qw(say signatures); 
no warnings "experimental::signatures"; 

print "Enter your first name: "; 
chomp(my $name1 = <STDIN>); 

print "Enter your last name: "; 
chomp(my $name2 = <STDIN>); 

say "Calling takesOneOrTwoScalars with 2 args"; 
takesOneOrTwoScalars($name1, $name2); 

say "Calling takesOneOrTwoScalars with 1 arg"; 
takesOneOrTwoScalars($name1); 

say "Calling takesOneOrTwoScalars with 0 args"; 
takesOneOrTwoScalars(); 

sub takesOneOrTwoScalars($firstName, $lastName="") 
{ 
    print "Hello, $firstName"; 
    if ($lastName) 
    { 
     say " $lastName"; 
    } 
    else 
    { 
     say ", I see you didn't give your last name."; 
    } 
} 
+3

Notez que cela ne génère qu'une erreur d'exécution * lorsqu'une liste d'arguments inappropriée est transmise. Je n'ai pas besoin de la fonctionnalité de signature pour cela. Par exemple: 'utiliser Carp; ... croak "Trop peu d'arguments pour takesOneOrTwoScalars" si @_ <1; croak "Trop d'arguments pour takeOneOrTwoScalars" si @_> 2' – amon

2

Certains qui peuvent être atteints avec prototypes (persub), dans une certaine mesure

Perl supporte une très limitée type de vérification d'argument à la compilation en utilisant le prototypage de fonction.
...
... l'intention de cette fonction est avant tout pour vous permettre de définir des sous-routines qui fonctionnent comme des fonctions intégrées

Par exemple, les sous-marins déclarés sub f1(\@) et sub f2($$) ne peut être appelé comme f1(@ary) (variable de tableau, avec @) et f2(SCALAR, SCALAR) ou il existe une erreur de compilation.

Mais il y a beaucoup plus à y faire, avec de nombreuses préoccupations subtiles; Veuillez lire les documents et les liens ci-dessous. Les prototypes sont et non comme les signatures de fonction dans les langages compilés et ne sont pas destinés à faire ce travail, même s'ils peuvent apparaître de cette façon. Même un léger abus peut conduire à des bugs subtils. Voir

Tout cela étant dit, ils peuvent être utile si elle est utilisée de façon appropriée. Voir les commentaires de ikegami sous OP.