2

Running ActiveState Perl 5.10.1 on win32.

How is it that this code:

die(defined($r->unparsed_uri =~ '/(logout.pl)?$'));

...dies with 1, whereas changing the same line to say this:

die($r->unparsed_uri =~ '/(logout.pl)?$');

...dies with Use of uninitialized value in die?

How is it defined yet uninitialized? I thought uninitialized meant undefined.

Kev
  • 15,899
  • 15
  • 79
  • 112

2 Answers2

8

In the first case, the matching operation is taking place in scalar context. In the second case, it's taking place in array context, almost as if you had written:

my @groups = $r->unparsed_uri =~ '/(logout.pl)?$';
die @groups;

If $r->unparsed_uri matches the pattern, but $1 is undefined because the matched string ended with "/", then @groups will be an array of length 1, containing the single element undef.

Put it all together, it's as if you'd said:

die(undef);
Sean
  • 29,130
  • 4
  • 80
  • 105
  • Oh, and I should have mentioned, if it's not obvious, that you can get the behavior you were expecting with die(scalar($r->unparsed_uri =~ '/(logout.pl)?$')); – Sean Feb 02 '10 at 21:36
2

Do you have warnings enabled?

Given

#!/usr/bin/perl -l

use strict; use warnings;

my $uri;

die(defined($uri =~ '/(logout.pl)?$'));

I get

Use of uninitialized value $uri in pattern match (m//) at E:\t.pl line 7.
1 at E:\t.pl line 7.

which explains what is going on.

$uri is not defined, so you get a warning for using that in m//. Because $uri is not defined, the result of the match is false but defined. Hence, defined returns true and die outputs 1.

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
  • 1
    I don't think it needs to be `undef =~ /(bar)?/` - I think `"foo" =~ /(bar)?/` could produce the reported behavior as well. –  Feb 02 '10 at 21:30
  • @fennec I just described why the OP saw the behavior he saw. What is inside the `defined(...)` is false but defined. `$r->unparsed_uri` is not both uninitialized and defined as the title of the question implies. – Sinan Ünür Feb 02 '10 at 22:15