2010-10-23 4 views
5

J'ai ce programme qui ne fonctionne pas comme prévu. Aidez moi.Pourquoi ma boucle Perl est-elle désactivée par un à la fin?

Je veux imprimer un en-tête de ligne.

Si l'entrée est 4, je souhaite afficher 1|2|3|4.

Cela ne fonctionne pas comme tout, si je code en dur la valeur $count cela fonctionne partiellement mais le dernier nombre est manquant.

sub printC { 
     my $count = @_; 
     # count = 4 # works partially only prints 1|2|3 
     for(my $i=1;$i<$count;$i++) { 
       print "$i|"; 
     } 
     print $i; 
} 
$count = 2; 
&printC($count); 
print "\n"; 

Répondre

11

Le problème est ici:

my $count = @_; 

L'affectation se passe dans un contexte scalaire qui attribue le nombre d'éléments dans le tableau @_-$count, que votre cas est 1, comme vous êtes passant argument 1 à la fonction.

Pour résoudre ce problème, vous pouvez le faire:

my ($count) = @_; 

ou

my $count = $_[0]; 

ici est un autre problème:

for(my $i=1..... 
    ^^ 

En utilisant my vous avez fait $ilocale à le corps de for et il ne sera pas disponible en dehors de il. Donc, votre print final en dehors du for n'imprime rien. Pour corriger ce mouvement la déclaration de $i en dehors de la boucle:

sub printC { 
     my ($count) = @_; 
     my $i; 
     .... 

Assurez-vous toujours un point d'écrire

use strict; 

en haut de votre programme qui vous permet d'attraper ces bugs.

Le perl façon de faire ce que votre fonction est fait:

print join('|',1..$count); 
+0

Je suppose que nous ferions une bonne équipe de codage synchronisée –

+0

J'aime la façon perl. – Tom

+0

Merci pour la mini leçon. – user485167

1

$i n'existe pas une fois que vous avez quitté la boucle for à cause de l'endroit où elle est déclarée.

Vous pouvez faire

sub printC { 
    my ($count) = @_; 
    my $i; 
    for ($i = 1; $i < $count; $i++) { 
     print "$i|"; 
    } 
    print $i; 
} 

Encore plus simple:

sub printC { 
    my ($count) = @_; 
    print join("|", 1 .. $count) . "\n"; 
} 
5

Un vrai hacker Perl peut écrire quelque chose comme ceci:

sub printC { 
    my $count = shift; 
    print join "|", (1 .. $count); 
} 

Une fois que vous comprenez comment cela fonctionne, vous Vous constaterez que vous en avez appris plus sur Perl.:-)

0

Un autre bit de "être plus Perlish" est de ne pas utiliser la boucle for de style C. Il est presque jamais besoin d'utiliser un for de style C en Perl.

Au lieu de

for(my $i=1;$i<$count;$i++) { ... } 

utilisation

for my $i (1 .. $count) { ... } 

Ils sont presque équivalent, à l'exception de la dernière version est à la fois plus facilement lisible et plus résistant aux erreurs hors par un. (La raison pour laquelle votre code n'imprimait que 1|2|3 au lieu de 1|2|3|4 est que le test dans votre style C for vérifiait $i<$count alors qu'il aurait dû être $i<=$count - c'est une erreur très commune avec les boucles for de style C qui évitent complètement.)

De même, ne préfixez pas vos sous-appels avec &. C'est une survivance de Perl 4 qui n'est plus nécessaire dans Perl 5 et a des effets secondaires dont vous n'êtes probablement pas conscients et que vous ne voulez probablement pas. Il suffit d'utiliser printC($count) au lieu de &printC($count).

Mais, oui, dans ce cas particulier, join est probablement une meilleure approche que for de toute façon.

Questions connexes