2013-06-17 4 views
1

Ceci est une sorte de question Perl n00b, mais je n'ai pas trouvé une réponse claire et compréhensible par moi-même en ligne.Déclaration de la fonction Perl

J'ai ce code:

1.sub remCH(); 
2.#some stuff 
3.$line = remCH($line); 
4. 
5.sub remCH() { 
6.$rem = shift; 
7.$rem = chomp($rem); 
8.return ($rem); 
9.} 

Je reçois toujours l'erreur suivante lors de l'exécution de ce code (ligne 24 serait la ligne 3 dans le code ci-dessus):

Too many arguments for main::rem_CRLF at ./make_csv.pl line 24, near "$line)" 

D'après ce que je comprends c'est parce que la fonction est configurée pour renvoyer quelque chose mais quand je l'ai déclarée, elle a été déclarée comme "vide".

Comment déclarer une fonction comme ci-dessous ???

sub remCH(string/integer); 

Répondre

5
  • Vous devez simplement supprimer la déclaration de fonction (ou "prototype", comme ils sont connus en Perl) en ligne # 1. Votre erreur est due au fait que le prototype (remCH()) a déclaré la fonction pour avoir une signature "paramètres zéro", alors que votre appel lui passe un paramètre. Le type de retour n'a rien à voir avec ça.

    Il existe des cas d'utilisation valides pour les prototypes en Perl, mais à moins que vous ne sachiez pourquoi vous souhaitez concevoir votre code de cette façon, la règle de base est de ne JAMAIS utiliser un prototype. Voir ce SO message:

    Why are Perl 5's function prototypes bad?

  • En outre, selon un commentaire sage plusplus, j'ai manqué que vous aviez «() » dans la définition de la fonction en ligne 5. Contrairement à C, vous ne les avez pas besoin dans Perl - déposez-les s'il vous plaît. Ils transforment la définition de la fonction en un autre prototype.


Cela dit:

  • vous pouvez prototyper un sous-marin qui prend 1 paramètre scalaire en utilisant remCH($) prototype
  • vous pouvez avoir des méthodes qui vérifient leurs types en passant au framework Moose orienté objet
+0

Donc, pour traduire ce que vous avez J'ai dit, je devrais enlever la ligne un et je devrais aller bien, non? : D – Lucian

+0

@ user2493988 - exactement. – DVK

+0

et supprimer le prototype sur la déclaration de la deuxième fonction afin qu'il devienne 'sub remCH {' ... – plusplus

3

Perl n'a pas de signatures de type ou de paramètres formels, contrairement à d'autres langages comme C:

// C code 
int add(int, int); 

int sum = add(1, 2); 

int add(int x, int y) { 
    return x + y; 
} 

Au lieu de cela, les arguments sont tout simplement passé en liste plate. Toute validation de type se produit à l'intérieur votre code; vous devrez l'écrire manuellement. Vous devez décompresser l'arglist en variables nommées vous-même.Et vous ne prédéclarer généralement pas vos sous-routines:

my $sum = add(1, 2); 

sub add { 
    my ($x, $y) = @_; # unpack arguments 
    return $x + $y; 
} 

Si vous prédéclarer vos sous-marins, vous obtenez les éléments suivants:

  1. Vous pouvez appeler les sous-marins sans parens
  2. Vous pouvez modifier les arguments de façon sont analysés avec des « prototypes »

Un prototype peut dire

  • évaluer cet argument dans un contexte scalaire: sub foo($), ou
  • cet argument doit être une variable de hachage, s'il vous plaît le transmettre comme référence: sub foo(\%) ou
  • ce sous prend aucun argument: sub foo() , etc.

Ne les utilisez pas pour valider le nombre d'arguments. En fait, ne les utilisez pas du tout; ils provoquent une action à distance. Ils ne sont pas utiles pour la validation de type non plus.

Votre erreur provient du fait que vous avez déclaré votre sous-élément comme étant nul, cela a causé une erreur d'analyse . Si vous souhaitez pouvoir déclarer vos sous-programmes avec des paramètres nommés, vous pouvez utiliser un module qui les implémente. Il y a quelques mises en garde:

  • Ces modules ne sont pas très répandus, ne les utilisez donc que pour des projets internes où la portabilité n'est pas un problème.
  • Ils ne fonctionnent que sur les nouveaux Perls
  • Ils souvent gâcher vos numéros de ligne :(

Une bonne mise en œuvre est Method::Signatures qui permet également le type de validation (et la valeur):

use Method::Signatures; 

my $sum = add(1, 2); 

func add(Int $x, Int $y) { 
    return $x + $y; 
} 

Cependant , ces "signatures" ont rien à faire avec les prototypes de sous-marins.

+0

de Perl Merci d'avoir expliqué cela. Je pense que je vais prendre le chemin court et juste supprimer toutes les pré-déclarations des sous-marins – Lucian

+0

+1 pour Method :: Signatures – DVK

Questions connexes