Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Bug? Use of uninitialized value $1 in substitution iterator

by clinton (Priest)
on Mar 04, 2009 at 12:50 UTC ( #748116=perlquestion: print w/ replies, xml ) Need Help??
clinton has asked for the wisdom of the Perl Monks concerning the following question:

Hi all

Is this a bug, or just a bad regex?

sub match { no warnings; my $value = shift @_; $value =~ s{^(?:aa(bb))?.*}{$1}i; return $value; } sub match_warn { use warnings; my $value = shift @_; $value =~ s{^(?:aa(bb))?.*}{$1}i; return $value; } print match('aabbcc')."\n"; # 'bb' print match('abbcc')."\n"; # '' print match_warn('aabbcc')."\n"; # 'bb' print match_warn('abbcc')."\n"; # Use of uninitialized value $1 +in substitution iterator

The way I would have read that is that the capture would contain the empty string, rather than undef and so wouldn't have thrown an unintialized value warning. Is my assumption correct, which would mean that this is a bug (in 5.8.8 and 5.10), or is there a better way to write this regex.

(Note: this regex is a simplified example of a substitution which is intended to retain a part of a string (if the surrounding text matches), and if not, to set the string to the empty string).

Comment on Bug? Use of uninitialized value $1 in substitution iterator
Select or Download Code
Re: Bug? Use of uninitialized value $1 in substitution iterator
by moritz (Cardinal) on Mar 04, 2009 at 12:55 UTC
    No, the regex engine has it right. Since the capturing group didn't match, $1 is undef. If $1 contained the empty string, it would mean that the associated capturing group matched a zero-length string (not possible in your example, but in general it's possible).

    I don't see a reason to change the regex though, if it does what you want. Just switch off the warning.

      OK, fair enough. This same code started throwing up errors today which it wasn't throwing before - I'd refactored some other code around it - so it had me worried.

      My solution was, as you suggest, to turn of those warnings.

      thanks Moritz

Re: Bug? Use of uninitialized value $1 in substitution iterator
by bellaire (Hermit) on Mar 04, 2009 at 13:01 UTC
    $1 is undefined, and any use of undef will trigger the warning. You can use the following regex if you don't want to turn the warnings off:
    s{^(?:aa(bb))?.*}{defined($1)?$1:q{}}ei;
    The e switch lets you use code for the replacement, so you can test whether $1 is defined before using it, and if it's not defined, use the empty string instead.
Re: Bug? Use of uninitialized value $1 in substitution iterator
by ikegami (Pope) on Mar 04, 2009 at 15:28 UTC
    Perl distinguishes between a capture that wasn't encountered in the match and a capture that matched zero characters.
    use Data::Dumper qw( Dumper ); '' =~ / ^ ( (?: ( bb ) # $2 )? ) # $1 $ /x; local $Data::Dumper::Useqq = 1; local $Data::Dumper::Terse = 1; local $Data::Dumper::Indent = 0; print('$1 = ', Dumper($1), "\n"); print('$2 = ', Dumper($2), "\n");
    $1 = "" $2 = undef
      nicely explained

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://748116]
Approved by sundialsvc4
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (13)
As of 2014-09-16 13:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (24 votes), past polls