Trying to untaint some variables in Perl, and the following code works great:
if ($year =~ /^(\d{4})$/) {
$year = $1;
} else {
&invalid("year");
}
In the above instance, $1 contains $year if valid. However, when using the ?:
operator, $1 contains "1" when valid:
($year =~ /^(\d{4})$/) ? $year = $1 : &invalid("year");
Anyone see where I might be at fault? I'm confused why this is happening. It's only happening on this machine. Or rather, I have successfully used the ? operator for returning proper match variables for years. I haven't tried this piece of code on any other machine yet.
This is Perl, v5.8.8 built for x86_64-linux-thread-multi
Be careful about precedence here.
Contrast http://codepad.org/vEPnhWfH which works as expected, with http://codepad.org/nXVU5CA7 which does not. Of course, I tweaked the code a little bit to avoid calling invalid
, but I suspect this may be at the root of the problem.
In both cases, though $1
contains "2011", so perhaps you should show additional code, as requested in the first comment by mu.
UPDATE
I changed the codepad examples to use the call to &invalid
and the error does not show up.
sub invalid {
print("INVALID\n");
}
sub check_with_if {
print("Trying with if-statement\n");
my $year = shift;
if ($year =~ /^(\d{4})$/) {
$year = $1;
} else {
&invalid($year);
}
print("\$1 is $1 and \$year is $year"."\n");
}
sub check_with_conditional {
print("Trying with conditional expression\n");
my $year = shift;
($year =~ /^(\d{4})$/) ? $year = $1 : &invalid($year);
print("\$1 is $1 and \$year is $year"."\n");
}
check_with_if("2011");
check_with_conditional("2011");
Output is
Trying with if-statement
$1 is 2011 and $year is 2011
Trying with conditional expression
$1 is 2011 and $year is 2011
http://codepad.org/z22GMEcn
EDIT 2 Also works on 5.12.3 on the Mac.
I agree with Jonathan that you may have found a bug in 5.8.8 that has been fixed since. If you are incredibly curious you can work your way through the Perl changes, such as:
Damien Conway's Perl Best Practices explains some of the pitfalls of using the match variables $1
and so on, one of them is that:
$1
does not become undef
, but it preserves its previous value (which of course, in most cases is undef)My intuition tells me that you have a problem with contexts - your expression might be evaluated in scalar context, thus returning the number of matches when it is valid.
So, I would try rewriting the code like:
($year) = ( $year =~ /^(\d{4})$/) or &invalid("year");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With