2010-02-02 8 views
2

Запуск ActiveState Perl 5.10.1 на win32.Может ли значение быть неинициализированным, но все еще определено в Perl?

Как получилось, что этот код:

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

... умирает с 1, в то время как изменения в той же строке, чтобы сказать это:

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

... умирает с Use of uninitialized value in die?

Как это defined еще uninitialized? Я думал, что uninitialized означает undefined.

+1

Я держу пари, что это всего лишь фанки-скаляр-vs-list-context. – fennec

ответ

8

В первом случае операция сопоставления выполняется в скалярном контексте. Во втором случае, это происходит в контексте массива, почти как если бы вы написали:

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

Если $r->unparsed_uri соответствует шаблону, но $1 не определен, так как соответствует строка закончилась «/», то @groups будет быть массивом длины 1, содержащим единственный элемент undef.

Положите все это вместе, это как если бы вы сказали:

die(undef); 
+0

Кажется, fennec был прав. Спасибо за объяснение! – Kev

+0

О, и я должен был упомянуть, если это не очевидно, что вы можете получить поведение, которое ожидали с помощью die (скалярный ($ r-> unparsed_uri = ~ '/(logout.pl)?$')); – Sean

2

ли вы включили предупреждения?

Учитывая

#!/usr/bin/perl -l 

use strict; use warnings; 

my $uri; 

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

Я получаю

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

, который объясняет, что происходит.

$uri не определен, поэтому вы получите предупреждение об использовании этого в m//. Поскольку $uri не определен, результатом совпадения является false, но определено. Следовательно, defined возвращает true и die выходы 1.

+1

Я не думаю, что это должно быть 'undef = ~/(bar)? /' - Я думаю, что '' foo "= ~/(bar)? /' Также может привести к сообщаемому поведению. – fennec

+0

@fennec Я только что описал, почему OP видел поведение, которое он видел. То, что находится внутри 'defined (...)', является ложным, но определено. '$ r-> unparsed_uri' не является неинициализированным и определяется как название вопроса. –