2009-09-29 3 views
19

Le module List::MoreUtils indique que vous utilisez les variables $a et $b lorsque vous fournissez le BLOCK correspondant à la fonction pairwise. Par exemple:

use strict; 
use warnings; 
use List::MoreUtils qw'pairwise'; 

my @x = (1 .. 5); 
my @y = (11 .. 15); 
my @sums = pairwise { $a + $b } @x, @y; 

Mais quand je fais ça, je reçois des avertissements comme ceci:

 
Name "main::b" used only once: possible typo at try.pl line 7. 
Name "main::a" used only once: possible typo at try.pl line 7. 

Y at-il une façon élégante de traiter ce problème?

Mise à jour:

Voir la answer by Ether pour v5.19.6 perl et au-delà: le problème est résolu.

+1

Cela ne semble pas avoir été signalé précédemment, donc je viens de le faire à https://rt.cpan.org/Ticket/Display.html?id=65629 – Ether

Répondre

23

Dépend de ce que vous considérez comme élégant.

no warnings qw(once); 
our ($a, $b); 

L'un de ces deux suffira. Vous pouvez même limiter leur portée assez facilement.

my @sums = pairwise { no warnings qw(once); $a + $b } @x, @y; 
my @sums = pairwise { our $a + our $b } @x, @y; 

La spécification explicite du package supprimera également l'avertissement. Si vous êtes dans main,

my @sums = pairwise { $::a + $::b } @x, @y; 
+0

Ce "pas d'avertissement" n'est pas nécessaire - au moins dans le premier exemple. –

+2

Si je peux citer la ligne suivant ce code, "l'un de ces deux suffira". –

+0

@Chris Lutz: désolé, mon malentendu. –

1

J'ai le même problème avec un module similaire que j'écris. La seule solution que j'ai trouvé (autre que d'utiliser les fonctions qui utilisent $a et $b deux fois, bien sûr) est de mettre cette ligne quelque part dans votre code:

$a = $b; # hack to disable warnings about "main::a" used only once 

Il ne fondamentalement rien, mais il ne désactive l'avertissement . Pensez à conserver le commentaire afin que les futurs responsables n'aient pas à lire dans vos pensées.

+0

Je suppose que vous vouliez dire '$ a = $ a' :) – pwes

+1

@pwes - Non. Cela fait un moment mais IIRC donne l'avertissement à la fois sur '$ a' et' $ b'. '$ a = $ b' utilise parfaitement les deux, désactivant ainsi les avertissements sur chacun d'eux. Bien qu'il soit possible que l'une ou l'autre puisse avoir une valeur restante d'un bloc 'BEGIN', et que le code plus récent _could_ repose sur cette valeur (bien que la pensée me donne des cauchemars), donc' $ a = $ a; $ b = $ b; 'pourrait techniquement être meilleur. –

+0

OK, je pensais que vous vouliez l'utiliser à l'intérieur du bloc - dans ce cas, il _does_ quelque chose :) – pwes

2

Ajouter ce haut près de votre programme:

use vars qw($a $b); 

ou, si vous ne voulez pas la « obsolète » une partie de perldoc vars, il suffit d'ajouter:

our ($a, $b); 
+0

Je me souviens d'un endroit où l'on lisait' use vars qw ($ a $ b); 'foutu avec 'sort()' mais je n'arrive pas à le trouver dans perldoc, cela peut donc être le fruit de mon imagination. –

+3

'use vars' est de portée paquet alors que' notre' est lexicalement portée au bloc contenant, donc du point de l'assainissement de l'environnement, je préfère 'notre' ... – ephemient

6

Ceci est probablement un bogue dans List::Util.

globalement Désactivation des avertissements est probablement pas une bonne idée, mais vous pouvez faire quelque chose comme ceci:

{ 
    no warnings 'once'; 
    return join("_", @monsters) if @monsters && List::Util::reduce { $a && $b // 0 > 0 } 1,@monsters; 
} 

Ce éteindrais la catégorie d'alerte pertinente pour cette partie du code seulement.

6

Oui, ce n'est pas toi. Vous ne pouvez pas avertir 'une fois'; ou vous pouvez prédéclarer $ a et $ b pour qu'ils ne soient plus utilisés une seule fois.

our ($a, $b); 

fait l'affaire. J'ai tendance à préférer cela parce qu'il ne désactive pas les avertissements pour quelque chose d'autre, et c'est un peu plus descriptif.

4

À partir de perl 5.19.6, this warning is disabled pour toutes les utilisations de $a et $b partout.

+0

Merci, Ether. J'ai ajouté une mise à jour à la question aussi. – FMc

Questions connexes