tags:

views:

217

answers:

5

The List::MoreUtils module indicates that you use the variables $a and $b when supplying the BLOCK that goes with the pairwise function. For example:

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

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

But when I do that, I get warnings like this:

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.

Is there an elegant way to deal with this problem?

+1  A: 

I have the same problem with a similar module I'm writing. The only solution I've found (other than using functions that use $a and $b twice, of course) is to put this line somewhere in your code:

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

It basically does nothing, but it does disable the warning. Consider keeping the comment so future maintainers don't have to read your mind.

Chris Lutz
+11  A: 

Depends on what you consider elegant.

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

One of these two will suffice. You can even limit their scope pretty easily.

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

Explicitly specifying the package will suppress the warning too. If you're in main,

my @sums = pairwise { $::a + $::b } @x, @y;
ephemient
This "no warnings" is not necessary - at least in first example.
depesz
If I may quote the line following that code, "One of these two will suffice."
Chris Lutz
@Chris Lutz: sorry, my misunderstanding.
depesz
@ephemient Thanks for the response. The last option (specifying the full package) did not eliminate the warning in my example.
FM
Hmm, it eliminates the warning for me with Perl 5.10.0 (without any `use feature`). Well, I prefer the `our` method anyhow...
ephemient
+1  A: 

Add this near top of your program:

use vars qw( $a $b );

or, if you don't like the "obsolete" part of perldoc vars, simply add:

our ( $a, $b );
depesz
I remember somewhere reading that `use vars qw($a $b);` messed with `sort()` but I can't seem to find it in perldoc, so it may just be a figment of my imagination.
Chris Lutz
`use vars` is package-scoped while `our` is lexically scoped to the containing block, so from the point of environmental sanitation, I prefer `our`...
ephemient
+6  A: 

This is probably a bug in List::Util.

Turning off warnings globally is probably not a good idea, however you could do something like this:

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

This would turn off the relevant warning category for that part of the code only.

szbalint
+3  A: 

Yep, it's not you. You can no warnings 'once'; or you can predeclare $a and $b so that they will not be used once anymore.

our ($a, $b);

does the trick. I tend to prefer that because it doesn't turn off warnings for anything else, and it's a bit more descriptive.

masonk