Perl: Unexpected matching variables when using ?: Operator

Trying to disable some variables in Perl, and the following code works fine:

if ($year =~ /^(\d{4})$/) { $year = $1; } else { &invalid("year"); } 

In the above example, $ 1 contains $ year, if valid. However, when using the ?: $ 1 operator, it contains "1" if it is valid:

 ($year =~ /^(\d{4})$/) ? $year = $1 : &invalid("year"); 

Does anyone see where I can be to blame? I am confused why this is happening. This only happens on this machine. More truly, I successfully used? operator to return the correct matching variables for many years. I have not tried this piece of code on any other machine yet.

 This is Perl, v5.8.8 built for x86_64-linux-thread-multi 
+4
source share
3 answers

Observe priority here.

The contrast is http://codepad.org/vEPnhWfH , which works as expected, http://codepad.org/nXVU5CA7 , which is not. Of course, I changed the code a bit to avoid calling invalid , but I suspect that this may be at the root of the problem.

In both cases, although $1 contains "2011", so maybe you should show additional code, as requested in the first comment from mu.

UPDATE

I changed the code page examples to use the &invalid call and the error does not appear.

 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

 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 Mac.

I agree with Jonathan that you may have discovered a bug in 5.8.8, which has been fixed since then. If you're incredibly interested, you can go your way through Perl changes, for example:

+6
source

Damien Conway Perl's best solutions explain some of the errors in using $1 matching variables, etc., one of which is:

  • If the regular expression does not match anything, $1 does not become undef , but retains the previous value (which, of course, in most cases is undef)

My intuition tells me that you have a problem with contexts - your expression can be evaluated in a scalar context, thus returning the number of matches when it is valid.

So, I would try to rewrite the code as:

 ($year) = ( $year =~ /^(\d{4})$/) or &invalid("year"); 
+5
source

With Perl 5.14.1 (on MacOS X 10.7.1) this script works fine:

 use strict; use warnings; my $year = "1984"; sub invalid { my($year) = @_; print "Invalid year $year\n"; } if ($year =~ /^(\d{4})$/) { $year = $1; } else { &invalid("year"); } print "Year1: $year\n"; $year = "1984"; ($year =~ /^(\d{4})$/) ? $year = $1 : &invalid("year"); print "Year2: $year\n"; 

He produces:

 Year1: 1984 Year2: 1984 

If the same script creates a different answer in Perl 5.8.8, then, presumably, you hit the error that was fixed and the update is fine. If Perl 5.8.8 gives the same answer (like Perl 5.14.1), then you have not yet described your problem so that I can understand it and reproduce the problem.

+3
source

All Articles