Subject: | RequireCheckingReturnValueOfEval and "." concats |
Date: | Mon, 13 Jun 2011 10:31:54 +1000 |
To: | bug-Perl-Critic [...] rt.cpan.org |
From: | Kevin Ryde <user42 [...] zip.com.au> |
The current cvs RequireCheckingReturnValueOfEval doesn't seem to notice
concatenations before an "or". Eg.
eval $str1 . $str2 or die
gets
/tmp/x.pl:1:1:
Perl::Critic::Policy::ErrorHandling::RequireCheckingReturnValueOfEval
Return value of eval not tested
eval $str1 . $str2 or die
I struck this when writing
eval "#line ".(__LINE__+1)." \"".__FILE__."\"\n" . <<'HERE' or die;
to get a #line into an evalled string for any later error throws, stack
traces, etc out of here-document code.
It may be as easy as stepping across operators higher than "named
unary", though there's probably a place for a proper step across
whatever one or more args to builtins like eval etc.
Index: RequireCheckingReturnValueOfEval.pm
===================================================================
--- RequireCheckingReturnValueOfEval.pm (revision 4082)
+++ RequireCheckingReturnValueOfEval.pm (working copy)
@@ -13,9 +13,10 @@
use Readonly;
+use List::MoreUtils qw( any );
use Scalar::Util qw< refaddr >;
-use Perl::Critic::Utils qw< :booleans :characters :severities hashify >;
+use Perl::Critic::Utils qw< :booleans :characters :severities hashify precedence_of >;
use base 'Perl::Critic::Policy';
our $VERSION = '1.116';
@@ -57,6 +58,19 @@
$following,
);
+ # eg. eval $str1 . $str2 or die
+ # skip past the "." operator to have $following at the "or"
+ # eval is a "named operator" like -x, so anything above that precedence
+ # goes into the evaluated expression
+ if (! $evaluated->isa('PPI::Structure')) {
+ while ($following
+ && $following->isa('PPI::Token::Operator')
+ && precedence_of($following) < precedence_of('-x')) {
+ $following = $following->snext_sibling;
+ $following = $following && $following->snext_sibling;
+ }
+ }
+
if ( $following and $following->isa('PPI::Token::Operator') ) {
return if $BOOLEAN_OPERATORS{ $following->content() };
return if q{?} eq $following->content;
Index: RequireCheckingReturnValueOfEval.run
===================================================================
--- RequireCheckingReturnValueOfEval.run (revision 4082)
+++ RequireCheckingReturnValueOfEval.run (working copy)
@@ -385,6 +385,41 @@
#-----------------------------------------------------------------------------
+## name boolean "or" etc
+## failures 0
+## cut
+
+eval $str or die;
+eval $str || die;
+eval $str and something();
+eval $str && something();
+
+eval $str1 . $str2 or die
+eval $obj->something or die
+
+eval $str . <<'HERE' or die
+some_code()
+HERE
+
+# a typical constructed expression which works the file and line into the
+# evaluated code and thus into any errors subsequently thrown from my_subr()
+eval "#line ".(__LINE__+1)." \"".__FILE__."\"\n" . <<'HERE' or die;
+sub my_subr {
+}
+1;
+HERE
+
+#-----------------------------------------------------------------------------
+
+## name boolean "or" etc, not yet done
+## TODO method call parameters not handled yet
+## failures 0
+## cut
+
+eval $obj->something() or die
+
+#-----------------------------------------------------------------------------
+
##############################################################################
# $URL$
# $Date$