Pourquoi utiliser strict et avertissements?

104

Il me semble que de nombreuses questions de la balise Perl pourraient être résolues si les gens utilisaient:

use strict;
use warnings;

Je pense que certaines personnes considèrent que cela s'apparente à des roues d'entraînement, ou à des complications inutiles, ce qui n'est clairement pas vrai, car même des programmeurs Perl très qualifiés les utilisent.

Il semble que la plupart des gens qui maîtrisent Perl utilisent toujours ces deux pragmas, alors que ceux qui bénéficieraient le plus de leur utilisation le font rarement. Donc, j'ai pensé que ce serait une bonne idée d'avoir une question à laquelle établir un lien pour encourager les gens à use strictet warnings.

Alors, pourquoi un développeur Perl use strictet warnings?

TLP
la source
14
Je me demande toujours pour des trucs comme celui-ci pourquoi ils n'en font pas simplement la valeur par défaut et obligent les développeurs à desserrer activement les choses, où est leuse loose;
Paul Tyng
12
Comme beaucoup de choses intéressantes et utiles, Perl a commencé comme un hack, comme un outil pour celui qui l'invente. Plus tard, il est devenu plus populaire et un nombre croissant de personnes non qualifiées ont commencé à l'utiliser. C'est à ce moment-là que vous commencez à penser que quelque chose comme use strictc'était une bonne idée mais que la rétrocompatibilité est déjà devenue un réel problème pour vous :-(
Daniel Böhmer
14
@JB Nizet, @Paul T., En fait, use strict;est activé par défaut lorsque vous demandez le langage Perl 5.12 (ou supérieur). Essayez perl -e"use v5.012; $x=123;". no strict;l'éteint réellement.
ikegami
1
Bien qu'en fin de compte votre argument soit vrai, plus nous le disons, plus les gens l'entendront peut-être. Il y a eu des rumeurs ces derniers temps pour essayer de rendre disponibles plus / meilleurs / modernes didacticiels Perl et certainement des avertissements stricts seront au-dessus de chacun d'entre eux. Pour le mien, je prévois d'avoir s / w en haut de chaque extrait, juste pour que tous les débutants le voient à chaque fois
Joel Berger
5
@JoelBerger Non, en fait, ce n'est rien de tel. Comme je l'ai dit, il n'y a que des mots similaires dans le titre. C'est pour la rétrocompatibilité. est la première phrase de la réponse acceptée, comment proposez-vous que cela s'applique à ma question?
TLP

Réponses:

83

Pour commencer, use strict;(et dans une moindre mesure, use warnings;) aide à trouver des fautes de frappe dans les noms de variables. Même les programmeurs expérimentés font de telles erreurs. Un cas courant est d'oublier de renommer une instance d'une variable lors du nettoyage ou de la refactorisation du code.

L'utilisation de use strict; use warnings;rattrape de nombreuses erreurs plus tôt qu'elles ne le seraient autrement, ce qui facilite la recherche des causes profondes des erreurs. La cause première peut être la nécessité d'une vérification d'erreur ou de validation, et cela peut se produire indépendamment de la compétence du programmeur.

Ce qui est bien avec les avertissements Perl, c'est qu'ils sont rarement faux, donc leur utilisation est pratiquement gratuite.


Lecture connexe: Pourquoi utiliser my?

ikegami
la source
2
@TLP, je ne suis pas sur le point de faire une étude pour quantifier à quel point cela aide. Il devrait suffire de dire qu’ils aident sans condition.
ikegami
1
Pourquoi est-il alors rendu facultatif s'il présente tant d'avantages? Pourquoi ne pas l'activer par défaut (comme quelqu'un l'a commenté ci-dessus)? Est-ce pour des raisons de compatibilité?
Jean du
4
@Jean, rétrocompatibilité. Notez qu'il use strict;est activé par défaut si vous utilisez la version 5.12 ou une version plus récente de la langue ( use 5.012;).
ikegami du
@Jean si vous écrivez un script simple, vous ne voulez vraiment pas être alerté par des avertissements sur les noms de gestionnaires de fichiers ou pour ne pas avoir déclaré la variable avant de les utiliser :-)
user2676847
28

Apparemment, use strictdevrait (doit) être utilisé lorsque vous voulez forcer perl à coder correctement, ce qui pourrait forcer la déclaration, être explicite sur les chaînes et les subs, c'est-à-dire les mots nus ou utiliser les refs avec prudence. Remarque: s'il y a des erreurs, use strict annulera l'exécution s'il est utilisé.

Bien que use warnings;cela vous aidera à trouver des erreurs de frappe dans le programme, comme si vous avez manqué un point-virgule, vous avez utilisé «elseif» et non «elsif», vous utilisez une syntaxe ou une fonction obsolète, peu importe ce que vous voulez. Remarque: l'utilisation d'avertissements ne fournira que des avertissements et poursuivra l'exécution, c'est-à-dire n'interrompra pas l'exécution.

Quoi qu'il en soit, il vaudrait mieux entrer dans les détails, ce que je précise ci-dessous

De perl.com (mon préféré):

utilisez des 'vars' stricts;

ce qui signifie que vous devez toujours déclarer les variables avant de les utiliser.

Si vous ne déclarez pas, vous obtiendrez probablement un message d'erreur pour la variable non déclarée

Le symbole global "$ variablename" nécessite un nom de package explicite à la ligne 3 de scriptname.pl

Cet avertissement signifie que Perl n'est pas exactement clair sur la portée de la variable. Vous devez donc être explicite sur vos variables, ce qui signifie soit les déclarer avec mypour qu'elles soient limitées au bloc courant, soit y faire référence avec leur nom complet (par exemple: $ MAIN :: variablename).

Ainsi, une erreur de compilation est déclenchée si vous tentez d'accéder à une variable qui ne répond pas à au moins l'un des critères suivants:

  • Prédéfini par Perl lui-même, tel que @ARGV,% ENV et toutes les variables de ponctuation globales telles que $. ou $ _.

  • Déclaré avec notre (pour un global) ou mon (pour un lexical).

  • Importé d'un autre package. (L'utilisation de vars pragma simule une importation, mais utilisez notre à la place.)

  • Complètement qualifié en utilisant son nom de package et le séparateur de package double-virgule.

utilisez des 'subs' stricts;

Considérez deux programmes

# prog 1
   $a = test_value;
   print "First program: ", $a, "\n";
   sub test_value { return "test passed"; }
 Output: First program's result: test_value

# prog 2
   sub test_value { return "test passed"; }
   $a = test_value;
   print "Second program: ", $a, "\n";
 Output: Second program's result: test passed

Dans les deux cas, nous avons un sous test_value () et nous voulons mettre son résultat dans $ a. Et pourtant, lorsque nous exécutons les deux programmes, nous obtenons deux résultats différents:

Dans le premier programme, au moment où nous en arrivons $a = test_value;, Perl ne connaît aucun sous test_value (), et test_value est interprété comme une chaîne 'test_value'. Dans le deuxième programme, la définition de test_value () vient avant la $a = test_value;ligne. Perl considère test_value comme un sous-appel.

Le terme technique pour des mots isolés comme test_value qui pourraient être des sous-titres et des chaînes en fonction du contexte, d'ailleurs, est bareword . La gestion des mots nus par Perl peut prêter à confusion et provoquer des bogues dans le programme.

Le bogue est ce que nous avons rencontré dans notre premier programme, rappelez-vous que Perl test_value()n'attendra pas avec impatience de trouver , donc comme il n'a pas déjà vu test_value (), il suppose que vous voulez une chaîne. Donc, si vous use strict subs;, cela provoquera la mort de ce programme avec une erreur:

Bareword "test_value" n'est pas autorisé lorsque "strict subs" est utilisé à ./a6-strictsubs.pl ligne 3.

La solution à cette erreur serait
1. Utilisez des parenthèses pour indiquer clairement que vous appelez un sous-marin. Si Perl voit $ a = test_value () ;,
2. Déclarez votre sous avant de l'utiliser pour la première fois

use strict;
sub test_value;  # Declares that there's a test_value() coming later ...
my $a = test_value;  # ...so Perl will know this line is okay.
.......
sub test_value { return "test_passed"; }

3. Et si vous voulez l'utiliser comme une chaîne, citez-la.

Donc, cette restriction oblige Perl à traiter tous les barewords comme des erreurs de syntaxe. * Un mot nu est un nom nu ou un identifiant qui n'a aucune autre interprétation forcée par le contexte. (Le contexte est souvent forcé par un mot-clé ou un jeton à proximité, ou par la prédéclaration du mot en question.) * Donc, si vous voulez l'utiliser comme chaîne, citez-le et si vous voulez l'utiliser comme appel de fonction, prédéclarez-le ou utilisez des parenthèses.

Les mots nus sont dangereux en raison de ce comportement imprévisible. use strict; (or use strict 'subs';)les rend prévisibles, car les mots simples qui pourraient causer un comportement étrange à l'avenir feront mourir votre programme avant qu'ils ne puissent faire des ravages

Il y a un endroit où il est acceptable d'utiliser des mots nus même lorsque vous avez activé les sous-marins stricts: lorsque vous attribuez des clés de hachage.

$hash{sample} = 6;   # Same as $hash{'sample'} = 6
%other_hash = ( pie => 'apple' );

Les mots nus dans les clés de hachage sont toujours interprétés comme des chaînes, il n'y a donc pas d'ambiguïté.

utilisez des 'refs' stricts;

Cela génère une erreur d'exécution si vous utilisez des références symboliques, intentionnellement ou non. Une valeur qui n'est pas une référence ferme est alors traitée comme une référence symbolique . Autrement dit, la référence est interprétée comme une chaîne représentant le nom d'une variable globale.

use strict 'refs';

$ref = \$foo;       # Store "real" (hard) reference.
print $$ref;        # Dereferencing is ok.

$ref = "foo";       # Store name of global (package) variable.
print $$ref;        # WRONG, run-time error under strict refs.

utiliser des avertissements;

Ce pragma à portée lexicale permet un contrôle flexible sur les avertissements intégrés de Perl, à la fois ceux émis par le compilateur et ceux du système d'exécution.

De perldiag:

Ainsi, la majorité des messages d'avertissement des classifications ci-dessous, c'est-à-dire W, D & S, peuvent être contrôlés à l'aide du warningspragma.

(W) Un avertissement (facultatif)
(D) Une obsolescence (activée par défaut)
(S) Un avertissement sévère (activé par défaut)

J'ai énuméré certains des messages d'avertissement qui se produisent souvent ci-dessous par classifications. Pour des informations détaillées sur eux et d'autres messages, reportez-vous à perldiag

(W) Un avertissement (facultatif):

Argument manquant dans% s
Argument manquant pour -% c
(Vouliez-vous dire &% s à la place?)
(Vouliez-vous dire "local" au lieu de "notre"?)
(Vouliez-vous dire $ ou @ au lieu de%?)
'% S 'n'est pas une
longueur de référence de code () utilisée sur% s
Misplaced _ en nombre

(D) Une obsolescence (activée par défaut):

défini (@array) est obsolète
défini (% hash) est obsolète L'
utilisation obsolète de my () dans false conditionnel
$ # n'est plus prise en charge

(S) Un avertissement sévère (activé par défaut)

elseif devrait être elsif
% s trouvé là où l'opérateur attendu
(Opérateur manquant avant% s?)
(Point-virgule manquant sur la ligne précédente?)
% s jamais introduit
Opérateur ou point-virgule manquant avant% s
Problème de priorité: open% s doit être ouvert (% s)
Incompatibilité de prototype:% s vs% s
Avertissement: l'utilisation de "% s" sans parenthèses est ambiguë
Impossible d'ouvrir% s:% s

ikegami
la source
10

Ces deux pragmas peuvent identifier automatiquement les bogues dans votre code.

J'utilise toujours ceci dans mon code:

use strict;
use warnings FATAL => 'all';

FATALfait mourir le code sur les avertissements, tout comme le strictfait.

Pour plus d'informations, consultez: Soyez plus strict avec les avertissements d'utilisation FATAL => 'all';

Aussi ... Les sténoses, selon Seuss

toolic
la source
En fait, vous devez retarder l' FATAL => "all"exécution de la caisse, en attribuant à $SIG{__WARN__} = sub { croak "fatalized warning @_" };ou bien vous bousillez le compilateur en essayant de vous dire ce dont il a besoin.
tchrist
6
@tchrist: Cela a toujours fonctionné pour moi tel quel et tel que documenté. Si vous avez trouvé un cas où cela ne fonctionne pas comme documenté, veuillez corriger la documentation à l'aide de perlbug.
toolic
9

Il y a un bon fil sur les perlmonks à propos de cette question.

La raison fondamentale est évidemment que les avertissements stricts et les avertissements vous aident massivement à détecter les erreurs et à faciliter le débogage.

maussade
la source
3

Source :: Différents blogs

Use exportera les fonctions et les noms de variables vers l'espace de noms principal en appelant la fonction import () des modules.

Un pragma est un module qui influence certains aspects de la compilation ou du comportement d'exécution de perl. Les pragmas donnent des indications au compilateur.

Utilisez des avertissements - plaintes de Perl concernant les variables utilisées une seule fois, conversions incorrectes de chaînes en nombres,. Essayer d'écrire dans des fichiers qui ne sont pas ouverts. Cela se produit au moment de la compilation. Il est utilisé pour contrôler les avertissements.

Utilisez la portée stricte - déclarez les variables. Il est utilisé pour définir une sorte de discipline dans le script.Si des mots nus sont utilisés dans le code, ils sont interprétés.Toutes les variables doivent avoir une portée, comme my, our ou local.

Rahul Reddy
la source
1

La directive "use strict" indique à Perl d'effectuer des vérifications supplémentaires lors de la compilation de votre code. L'utilisation de cette directive vous fera gagner du temps lors du débogage de votre code Perl car elle trouve des bogues de codage courants que vous pourriez ignorer autrement.

MikasaAckerman
la source
0

Strict et avertissements garantissent que vos variables ne sont pas globales.

Il est beaucoup plus simple de pouvoir avoir des variables uniques pour des méthodes individuelles plutôt que d'avoir à garder une trace de chaque nom de variable.

$ _, ou aucune variable pour certaines fonctions, peut également être utile pour écrire du code plus compact plus rapidement.

Cependant, si vous n'utilisez pas strict et warnings, $ _ devient global!

Andreas Ährlund
la source
0
use strict;
use warnings;

Strict et warnings sont le mode du programme perl. Cela permet à l'utilisateur de saisir le code de manière plus libérale et plus que cela, ce code perl aura l'air formel et sa norme de codage sera efficace.

warnings signifie la même chose que -wdans la ligne perl shebang, donc il vous fournira les avertissements générés par le programme perl, il s'affichera dans le terminal

dhana govindarajan
la source