Je sais que dans un sous-programme à Perl, c'est une très bonne idée de conserver la "variable par défaut" maintenant, souvent la raison pour laquelle vous utilisez tout Perlvar dit est que mais ce que je trouve vraiment surprenant, c'est que, dans mon active 5.10.0 au moins, donc je trouve cette situation déroutant au mieux et j'adorerais entendre une explication définitive. Mind You, je me contenterais d'une manière balayée de conserver tous les variables magiques liées aux em> sans avoir à les énumérer comme dans: p> Ce qui est clairement un hack dégoûtant. Jusque-là, je m'inquiéterai que toute regex que je touche écrasera quelque chose que l'appelant ne s'attendait pas à être encombré. P> Merci! P> P> $ £ _ code> avec local code> avant de faire quelque chose avec elle, au cas où L'appelant l'utilise, par exemple: $ _ code> en premier lieu est que vous souhaitez utiliser des regexes, qui peuvent mettre Résultats dans des variables "magiques" utiles telles que 1 $ code>, 2 $ code> etc. Je voudrais aussi préserver ces variables aussi, mais je n'ai pas pu trouver de façon de faire ça. strong> p> @ + code> et @ - code>, lequel 1 $ code> etc. semblent dépendre de l'interne, reportez-vous aux «derniers submatchs réussi de la portée dynamique actuellement active». Mais même cela semble en attente avec mes expériences. Empiriquement, le code suivant imprime "AXAA" comme je l'avais espéré: p> LOCAL CODE> LINE CONSERVES TOUJOURS $ 1 CODE> STROND> - c'est-à-dire la réponse "Axxa" est produite! Il semble que la portée lexicale (non dynamique) du bloc fermé par le cornoir est en quelque sorte préservant la valeur de 1 $ code>. P>
3 Réponses :
Je ne suis pas sûr qu'il y ait une raison réelle d'être ce paranoïde sur toutes ces variables. J'ai réussi à utiliser Perl depuis près de dix ans sans avoir besoin d'utiliser un La réponse à votre question spécifique est la suivante: le nombre de variables de chiffres n'est pas un indifférent (même s'il existe une limite de mémoire difficile au nombre de matchs que vous pouvez travailler). Donc, il n'est pas possible de localiser toutes toutes en même temps. P> explicite code> dans ce contexte. P>
@Sinan, pas tout à fait. Ils sont tous déjà toujours toujours locaux () ized. Le questionneur est un peu confus par cela et peut-être par les subtilités des deux paradigmes de Scoping à Perl.
@Sinan: Caller-Save ne peut pas bien mettre à l'échelle sur les grands systèmes, car l'appelant doit toujours être conscient de ce que toutes les fonctions appelées encombrent, tout en bas du graphique de l'appel. Il est donc facile pour une modification de la mise en œuvre d'une fonction de bas niveau à gâcher avec une fonction de haut niveau. C'est bien pour les scripts de 100 lignes, mais si vous écrivez un gros système, vous devez être capable de pas de soin i> sur les détails de la mise en œuvre des fonctions que vous appelez.
Mais, voir, c'est la chose: je n'ai jamais eu de se soucier des détails de la mise en œuvre des fonctions que j'appelle (Eh bien, oublions Win32 :: Ole Code> pour un moment). Compte tenu de la clarification de la Circle, c'est évident pourquoi.
@Sinan: Je suppose que nous sommes chanceux dans ce cas :) En général, c'est une bonne idée de sauvegarder et de restaurer dans la fonction appelée plutôt que l'appelant, car si tout le monde le fait, il suffit de regarder ce que l'actuel Fonction Clobbers Pour décider quoi sauver - par opposition à avoir besoin de regarder toute la pile d'appels. Ceci s'applique également à un autre état global (par exemple répertoire actuel, binmode (), $ ?, $! Etc.) Sauf si bien sûr, vous souhaitez spécifiquement que la fonction modifie cet état.
@j_Random_hacker autre chose que le code de niveau supérieur est passé le répertoire plutôt que de fonctionner dans le répertoire actuel. Quant à l'écrivain de la bibliothèque localisant $! Code>: c'est juste bizarre. Le code d'appel doit uniquement vérifier $! Code> après une erreur.
@Sinan: Bien sûr, $! est un exemple faible, il n'y a aucune raison de le localiser. Mais concernant le répertoire actuel: Parfois, vous n'avez pas de choix, car la fonction peut avoir besoin d'exécuter un programme qui s'attend à ce que le répertoire actuel soit quelque part différent. (N'avez-vous vraiment pas expérimenté cela dans 10 ans de Perl?) En fait, ne pas changer de répertoire peut être un problème de sécurité: gnu.org/software/findutils/manual/html_mono/...
@j_Random_hacker J'apprécie l'exemple de la CWD, mais je pense que l'argument de la localisation d'un grand ensemble de variables spéciales n'est pas fort. Quoi qu'il en soit, j'ai oublié d'ajouter des smileys après le bizarre i> ci-dessus ;-)
Je ne m'inquiéterais que pour local () code> izing $ _ code>
Étant donné que YSTH a souligné que Perl localise efficacement ces variables, le point est discutable, mais si ce n'était pas le cas, je ne vois pas comment quelqu'un pouvait défendre l'idée qu'il ne "vaut pas" préservant ces variables. C'est pour exactement i> la même raison que tous les programmeurs préfèrent les variables locales (en Perl, lexicales) aux variables globales - car cela peut donc modifier les changements d'état mondial, ce qui nous permet de raisonner plus efficacement (et avec précision ) sur le flux de programme.
Peut-être que vous pouvez suggérer un meilleur libellé pour la documentation. La portée dynamique signifie tout au début du bloc de la joint ou du sous-programme, ainsi que tout au début de cet appel de bloc ou de sous-programme, etc. sauf em> que tous les blocs fermés sont exclus. P>
Une autre façon de le dire: "Derniers submatchs réussi dans la portée dynamique actuellement active" signifie qu'il existe implicitement un La plupart des mentions de la portée dynamique (par exemple, http: //perldoc.perl. Org / perlglossary.html # Scope ou http: //perldoc.perl. org / perlglossary.html # dynamique-scoping )
approche de l'inverse. Ils s'appliquent si vous pensez à un succès
regex comme implicitement effectuant un x $ x = $ x; code> au début de chaque bloc pour chaque variable. < / p>
local 1 $ code>, etc. p>
+1. 1 $ code> et ainsi de suite est automatiquement local () code> ized et la portée est confuse.
Merci très utile! Oui, j'ai été confondu par le terme "Portée dynamique", qui (pour une raison quelconque), j'ai pris pour exclure / ignorer des blocs. C'est un soulagement de savoir que 1 $ etc. sont implicitement localisés. (Basé sur vos liens, je suppose qu'il n'y a rien d'explicitement dans le Documents de Perl le disant?)
Je pense que vous vous inquiétez trop. La meilleure chose à faire est de gérer votre opérateur de match, enregistrez immédiatement les valeurs que vous souhaitez dans des variables significatives, puis laissez les variables spéciales à faire tout ce qu'ils font sans vous soucier d'eux:
my @array = $string =~ m/..../g;
Doivent être en désaccord là-bas :) Au fil des ans, j'ai remarqué que toute pratique de codage qui semble "improbable" de causer des problèmes (par exemple, s'appuyer sur 1 $, etc. ne pas changer d'appels à d'autres fonctions), finira par causer des problèmes sauf si est une garantie qu'il ne peut pas i>, donc de nos jours, je cherche des garanties. Heureusement, dans ce cas, YSTH a pu me montrer que Perl fournit une telle garantie.
Supposons que Perl ne soit pas réellement localisée automatiquement 1 $, etc. Ensuite, il est facile de voir à quel point votre extrait de code 1ère code serait fragile: Supposons que, dans le cadre de la maintenance, «si» devient "si ($ string = ~ m / ... (AC) ... / && quelque_other_test ()) {...} ". Tout fonctionne bien jusqu'à ce que quelqu'un ajoute une regex quelque part en profondeur dans les entrailles de certains_other_test (), à quel point $ trouvé commence mystérieusement de valeurs étranges. Seriez-vous d'accord pour dire qu'il s'agit d'un scénario d'entretien plausible?
Donc, un gars va dans le médecin et dit: «Ça fait mal quand je bouge mon bras comme ça!». Le médecin dit "Ne bouge pas ton bras comme ça!". Mon premier coup de code n'est pas fragile du tout. C'est votre changement qui est le problème. Je faisais volontiement les opérations isolées. Vous ne faites pas ce que je dis: enregistrez immédiatement le résultat.
"C'est [mon] change-là qui est le problème." C'est absolument correct. Mon point est que mon changement est le type de changement qui se passe tout le temps i> comme le code est maintenu. Votre code est correct aujourd'hui i>, mais l'expérience a enseigné que cela ne suffit pas - je veux du code susceptible de rester correct à l'avenir. C'est ce que j'appelle Code robuste i>. Encore une fois, cela n'est important que si vous maintenez un grand système sur une longue période. Je suis et ma philosophie est progressivement de plus en plus centrée sur la maintenance.
Je ne veux pas vous suggérer de supprimer toute possibilité de créer des bugs à l'avenir - si quelqu'un est suffisamment imprudent, ils introduiront des bugs. Mais il existe des moyens de réduire ce risque et de blâmer les changements d'État globaux en fait partie. Donc, s'il y a une manière sans coût (ou peu coûteux) de faire cela, je l'utiliserai.
Eh bien, faites ce que vous aimez, mais il n'y a absolument rien qui empêchera les gens de changer de bon code de travail en mauvais code brisé, peu importe ce que vous faites. Dans votre sens, il n'y a pas de code robuste et ne peut jamais être. Mon code est correct aujourd'hui et est correct demain et la semaine prochaine et l'année prochaine. Je ne ferai rien d'arrêter à quiconque d'introduire des bugs.
Le code parfaitement robuste n'existe pas, mais il y a un code plus robuste et un code moins robuste. "Rien que je n'ai fait arrêter quiconque d'introduire des bugs" - vous n'êtes pas sérieux, n'est-ce pas? Si oui, alors pourquoi se soucier de la modularité, de la séparation des préoccupations ou de tout autre principe de conception? Le point entier est de faire futurs i> les changements de code (a) plus faciles et (b) moins sujets de bug.
@j_Random_hacker: Si vous voulez continuer à débattre, simplement parce que vous vous ennuyez, allez ailleurs. Vous avez dit ce que vous voulez dire et j'ai dit ce que je veux dire. Nous ne sommes pas d'accord. Dire que cela ne va pas me faire d'accord avec vous.
Ce dernier commentaire me frappe comme un peu défensive, désolé si je semblais vous attaquer, j'essayais simplement de comprendre où vous venez de. Mais c'est bien si vous ne voulez pas élaborer plus loin, il y a plus à vie que de débattre (que je pense est ce que nous étions à la fois i> faire, BTW).
@Pilcrow: Je n'ai pas attrapé votre réponse, mais je l'ai vu dans un courriel de synthèse tellement m'a envoyé - je suppose que vous l'avez supprimé? Quoi qu'il en soit, je pensais que c'était une réponse utile et si vous avez lu ceci: je cherchais le 1er type de préservation. Le 2e était en fait ce que j'espérais que j'espérais pas i> se produira - cela équivaudrait à des choses qui "devraient" être locales "saignements" dans d'autres étendues, et oui, si je voulais ce genre de "préservation «Je voudrais simplement copier 1 $ et etc. dans d'autres variables locales que vous avez suggéré.