OVH Cloud OVH Cloud

opérateurs perl

2 réponses
Avatar
nicolas_laurent545
J'ai cherch=E9 la signification des op=E9rateurs de perl pour d=E9coder
next if(!$str || $str=3D~/=3D=3D=3D=3D=3D/);

SVP donnez moi une explication de cette commande afin que je puisse
l'adapter =E0 mon besoin.

Merci


sub get_data{
my ($input_file, $r_data) =3D @_;
my $str;

open(FH, "< $input_file") || die "$input_file: $!\n\n";
while($str =3D <FH>){
next if(!$str || $str=3D~/=3D=3D=3D=3D=3D/);

chomp $str;
$str =3D~ s/^\s*//;
$str =3D~ s/\s*$//;

if(!$r_data->{$str}){
$r_data->{$str} =3D 1;
}
else{
$r_data->{$str}++;
}
}
close FH;
}

2 réponses

Avatar
Paul Gaborit
À (at) 16 May 2006 15:07:37 -0700,
écrivait (wrote):
J'ai cherché la signification des opérateurs de perl pour décoder
next if(!$str || $str=~/=====/);


Et qu'à donner cette recherche ? ;-)

On peut réécrire cette ligne plus lisiblement :

next if ( ! $str || $str =~ m/=====/);

Ou mieux encore :

next if not $str or $str =~ m/======/;

Ce qui signifie : passer à l'itération suivante (du 'while') si $str
est faux ou si $str "matche" la chaîne '======'.

$str est faux si c'est la valeur 'undef' (ce qui ne devrait pas
arriver dans votre programme puisque c'est testé par le 'while'), la
chaîne vide (complètement) ou une chaîne contenant uniquement le
caractère 0. Ces deux dernières conditionscas ne peuvent jamais avoir
lieu non plus puisque $str contient toujours au moins le caractère de
fin de ligne. Cette première condition est donc totalement inutile
(sauf dans le cas extrême d'un fichier se terminant par le caractère 0
sans fin de ligne).

$str "matche" la chaîne '======' si elle contient 5 fois de suite le
caractère '='.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
tuser
wrote:
J'ai cherché la signification des opérateurs de perl pour décoder
next if(!$str || $str=~/=====/);

SVP donnez moi une explication de cette commande afin que je puisse
l'adapter à mon besoin.


Paul Gaborit a déjà répondu, mais laissez-moi, SVP, proposer
quelques modifications cosmétiques, sans modifier le fonctionnement:

sub get_data{
my ($input_file, $r_data) = @_;

my $str;
je propose de déplacer cette instruction vers le bas, dans le "while".

La règle: il vaut mieux de déclarer une variable à l'endroit où
elle est utilisé.

open(FH, "< $input_file") || die "$input_file: $!nn";
open my $fh, '<', $input_file or die "pb '$input_file', message: $!";


remplacer la variable globale "FH" par une variable lexicale (my $fh),
ce qui permet une fermeture automatique à la fin du subroutine, donc
le close à la fin n'est plus nécessaire.
Autrement, séparer le '<' et $input_file, c'est plus lisible.
Aussi, remplacer le "||" par "or", ce qui permet de virer les
paranthèses.
Finalement, rendre le message dans "die" plus lisible et virer les "n"
à la fin, ce qui permet d'afficher le numéro de ligne automatiquement
en cas de problème.

while($str = <FH>){
while (my $str = <$fh>) { chomp $str;


le "my" a été déplacé d'une ligne précédente
le "chomp" a été déplacé d'une ligne suivante

next if(!$str || $str=~/=====/);


comme déjà proposé par Paul Gaborit:

next if not $str or $str =~ m/======/;

chomp $str;
comme déjà proposé, déplacer cette ligne vers le haut


$str =~ s/^s*//;
$str =~ s/s*$//;
remplacer le "*" par un "+" (parce que le cas ou on trouve zéro "s",

on remplace "rien" par "rien", ce qui est inutile).

$str =~ s/^s+//;
$str =~ s/s+$//;

if(!$r_data->{$str}){
$r_data->{$str} = 1;
}
else{
$r_data->{$str}++;
}


il n'y a pas besoin de tester "if(!$r_data->{$str})", le "++" marche
parfaitement avec des valeurs "undef", donc je propose de remplacer les
6 lignes précédentes par une simple

$r_data->{$str}++;

}

close FH;
comme déjà dit, on peut virer la commande "close" car avec le nouveau

"my $fh", le close est maintenant automatique à la fin du subroutine.

}