Commits

Toby Inkster  committed d2d9309

$a and $b

  • Participants
  • Parent commits 7ff6d81

Comments (0)

Files changed (2)

File lib/List/MapMulti.pm

 		'standard' => \@EXPORT,
 		'default'  => \@EXPORT,
 		'nothing'  => [],
-		);
+	);
 }
 
 sub iterator_multi
 	if (@arrays)
 	{
 		my $iter = iterator_multi(@arrays);
+		
 		local $_ = $iter;
+
+		# Localise $a, $b
+		my ( $caller_a, $caller_b ) = do {
+			my $pkg = caller;
+			no strict 'refs';
+			\*{$pkg.'::a'}, \*{$pkg.'::b'};
+		};
 		
 		while (my @values = $iter->())
 		{
-			#$_ = \@values;
+			no strict 'refs';
+			(*$caller_a, *$caller_b) = \( @values[0, 1] );			
 			push @results, $code->(@values);
 		}
 	}
 use overload
 	'&{}' => sub { my $self = shift; sub { $self->next } },
 	'@{}' => sub { my $self = shift; [ $self->current ] },
-	;
+;
 
 BEGIN
 {
 as C<< $_[0] >>, C<< $_[1] >>, etc. The C<< $_ >> variable is set to a
 List::MapMulti::Iterator object which is used internally by C<map_multi>.
 
+For the special (but common) case where you're just mapping over two lists,
+C<< $a >> and C<< $b >> are aliased to C<< $_[0] >> and C<< $_[1] >>. You
+may need to do C<< our ($a, $b) >> to suppress warnings about variables
+being used only once.
+
 C<mapm> is exported by default, but C<map_multi> needs to be requested
 explicitly.
 
+use strict;
+use warnings FATAL => 'all';
+use Test::More;
+
+use List::MapMulti;
+
+my @numbers = ( 2 .. 10, qw< J Q K A > );
+my @suits   = qw< Spades Hearts Diamonds Clubs >;
+
+sub traditional ()
+{
+	my @results;
+	for my $number (@numbers)
+	{
+		for my $suit (@suits)
+		{
+			push @results, "$number of $suit";
+		}
+	}
+	\@results;
+}
+
+sub mapmulti_params ()
+{
+	[ mapm { "$_[0] of $_[1]" } \@numbers, \@suits ]
+}
+
+sub mapmulti_ab ()
+{
+	our ($a, $b);
+	[ mapm { "$a of $b" } \@numbers, \@suits ]
+}
+
+is_deeply mapmulti_params, traditional;
+is_deeply mapmulti_ab, traditional;
+
+done_testing;