J'aimerais pouvoir refaire un bloc de code est-ce possible? Comment faire?
Merci,Code:
1
2
3
4
5
6
7
8
9
10
11 BLOC ALIGN : { if (...){ REDO ALIGN } }
Version imprimable
J'aimerais pouvoir refaire un bloc de code est-ce possible? Comment faire?
Merci,Code:
1
2
3
4
5
6
7
8
9
10
11 BLOC ALIGN : { if (...){ REDO ALIGN } }
c'est à dire ? J'ai pas bien saisi ce que tu veux faire.
Je voudrais pouvoir refaire une portion de code qui n'est pas une boucle.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 BLOC ALIGN : { my @sort_sequences; for my $l (0..$#sequences){ if (defined $sequences[$l]){ push (@sort_sequences, @{$sequences[$l]}); } } for my $l (1..$#sort_sequences){ } # if(...) {refaire le bloc avec @sequences qui a été modifié} }
avec goto.
Code:
1
2
3
4
5
6
7
8 my $toto = 0; TUTU : { print "bloc\n"; $toto++; goto TUTU while ($toto <= 5); } print "fin\n";
Merci, je vais y regarder.
Comme il est interdit d'utiliser goto, il faut utiliser redo :
S'il n'y a pas d'ambigüité sur la boucle, le label est optionnel.Code:
1
2
3
4
5
6
7
8 my $toto = 0; TUTU : { print "bloc\n"; $toto++; redo TUTU while ($toto <= 5); } print "fin\n";
Comme indiqué dans le manuel de "redo" :
Citation:
Note that a block by itself is semantically identical to a loop
that executes once. Thus "redo" inside such a block will
effectively turn it into a looping construct.
See also "continue" for an illustration of how "last", "next",
and "redo" work.
Merci pour votre aide.
J'obtiens l'erreur
Citation:
Can't locate object method "REDO" via package "ALIGN" (perhaps you forgot to load "ALIGN"?) at CW_diff_seq_length3.pl line 172.
Où est mon erreur? Merci.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 ALIGN : { my @sort_sequences; for my $l (0..$#sequences){ if (defined $sequences[$l]){ push (@sort_sequences, @{$sequences[$l]}); } } my $consensus; for my $l (1..$#sort_sequences){ # si aucun alignement n'existe # on aligne $sort_sequences[$l] avec $sort_sequences[$l-1] if (!defined $consensus){ $consensus = &undef_consensus ($l, \@unalign_seq, \@sort_sequences); } # si un consensus existe # on l'aligne avec la séquence suivante else{ # Or one can pass the factory an alignment and one or more unaligned $consensus = &def_consensus ($sort_sequences[$l],$consensus, \@unalign_seq, \@sort_sequences); } } # si rien n'est trouvé on recommence sans la première séquence if (!defined $consensus) { # si il restait au moins 3 séquences if (@sort_sequences > 3){ # on remet la liste des séquences non alignées à zéro @unalign_seq = (); # ajout de la première séquence à la liste push @delete_acc, $sort_sequences[0]; # suppression de la première séquence dans les séquences à traiter shift @sort_sequences; # REDO avec le nouveau @sort_sequences contenant une séquence en moins REDO ALIGN; } else { push (@orga_without_consensus, $orga); } } else { # on indique dans le fichier log les séquences qui n'ont pas été prises if (@delete_acc != 0){ print $log_fh ($orga." **\t".@delete_acc."\t".$tot_seq."\t"); foreach my $val (@delete_acc){ my ($id, $seq) = split /_/, $val; print $log_fh "$id "; } print $log_fh "\n"; } if (@unalign_seq != 0){ print $log_fh ($orga."\t".@unalign_seq."\t".$tot_seq."\t"); foreach my $val (@unalign_seq){ my ($identity, $id, $seq) = split /_/, $val; $identity = sprintf ("%.2f", $identity); print $log_fh "$id ($identity) "; } print $log_fh "\n"; } print $cons_fh ">".$orga."_consensus\n$consensus\n"; } }
Perl est sensible à la casse, REDO et redo ne sont pas la même chose.
--
Jedaï
Pourrais-je savoir pourquoi goto est interdit ? Merci.
goto n'est pas recommandé en C, je vois pas pourquoi il ne le serait pas dans les autres langages (il destructure les langages structurés ; en l'occurrence, il permet de violer les règles d'une boucle et permettant d'aller "n'importe où", y compris dans une autre boucle, alors que redo, last sont des fonctionnalités de boucle).
En cherchant bien, il doit bien exister une règle dans le PBP pour ça ;)
Je ne dirais pas qu'il est interdit, mais il est rarement nécessaire, et il est toujours préférable d'utiliser l'un des contrôles de boucle à la portée et au sens plus restreint, controlé si c'est possible.
Evidemment il y a l'exception du "goto &sub" qui n'a de goto que le nom et peut-être utilisé pour implémenter une récursivité terminale à la fonctionnelle, ou certaines autres astuces tels qu'un AUTOLOAD invisible.
--
Jedaï
Ok, merci pour vos réponses.
Pour ma curiosité, pourquoi ce bloc ne doit pas être une boucle ?
Ce bloc de code ne pourrait-il pas être une fonction qui va retourner un état, et on boucle tant qu'on n'a pas l'état attendu ?
genre :
Comme ca on peut réutiliser le bloc de code comme on veut, des fois qu'une seule passe serait suffisante pour certains cas.Code:
1
2
3
4
5
6
7
8
9 while ($i == 1) { $i = &align; } ... sub align { ...... return(1) #a la place de redo }
@+
Mr6
Bien sur que tu peux écrire une fonction... surtout si tu sens qu'elle sera ré-utilisable ailleurs.
Tu peux d'ailleurs écrire ta boucle encore plus simplement :
Mais j'attire ton attention sur le fait que terminer une fonction dans une boucle ou un bloc de code avec un return (ou, en d'autres termes, terminer une fonction à plusieurs endroits dans cette fonction), n'est pas forcément une bonne chose. C'est notamment, il me semble, une règle de codage pour les logiciels aéronautiques (DO178) : un seul return par fonction. Cela permet, par exemple, de ne pas oublier de traiter des bouts de code situés entre une boucle et le return terminal de la fonction.Code:while ( align() ) { };
Cela dit, c'est couramment utilisé.