Commits

Toby Inkster committed 27f8f58

Fix for RT#94196 (conflicting uses of $_ in Type::Tiny::Duck), reported by DJERIUS

  • Participants
  • Parent commits 03c89e9

Comments (0)

Files changed (2)

lib/Type/Tiny/Duck.pm

 	sub {
 		my $var = $_[1];
 		local $" = q{ };
-		qq{ Scalar::Util::blessed($var) and not grep(!$var->can(\$_), qw/@methods/) };
+		# If $var is $_ or $_->{foo} or $foo{$_} or somesuch, then we
+		# can't use it within the grep expression, so we need to save
+		# it into a temporary variable ($tmp).
+		($var =~ /\$_/)
+			? qq{ Scalar::Util::blessed($var) and not do { my \$tmp = $var; grep(!\$tmp->can(\$_), qw/@methods/) } }
+			: qq{ Scalar::Util::blessed($var) and not grep(!$var->can(\$_), qw/@methods/) };
 	};
 }
 

t/40-regression/rt94196.t

+=pod
+
+=encoding utf-8
+
+=head1 PURPOSE
+
+Problematic inlining using C<< $_ >>.
+
+=head1 SEE ALSO
+
+L<https://rt.cpan.org/Ticket/Display.html?id=94196>.
+
+=head1 AUTHOR
+
+Diab Jerius E<lt>djerius@cpan.orgE<gt>.
+
+=head1 COPYRIGHT AND LICENCE
+
+This software is copyright (c) 2014 by Diab Jerius.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
+
+use strict;
+use warnings FATAL=> 'all';
+use Test::More;
+use Test::Fatal;
+
+use Type::Params qw( validate );
+use Types::Standard qw( -types slurpy );
+
+{
+	package Foo;
+	sub new { bless {}, shift }
+	sub send { }
+};
+
+my $type = Dict[ encoder => HasMethods ['send'] ];
+
+is(
+	exception {
+		my @params = ( encoder => Foo->new );
+		validate(\@params, slurpy($type));
+	},
+	undef,
+	"slurpy Dict w/ HasMethods",
+) or note( $type->inline_check('$_') );
+
+done_testing;