views:

76

answers:

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.

+8  A: 

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
Seems fennec was right. Thanks for the explanation!
Kev
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
+2  A: 

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
I don't think it needs to be `undef =~ /(bar)?/` - I think `"foo" =~ /(bar)?/` could produce the reported behavior as well.
fennec
@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