2012-06-27 1 views
3

Я пытаюсь проверить, определен ли элемент, используя функцию defined в Perl.В Perl, как использовать «определенную» функцию на элементах двумерного массива?

Код:

$mylist[0][0]="wqeqwe"; 
$mylist[0][1]="afasf"; 
$mylist[1][0]="lkkjh"; 

print scalar(@mylist), "\n"; 

if (defined($mylist[2][0])){print "TRUE\n";} 

print scalar(@mylist), "\n"; 

Выход

2 
3 

Перед использованием defined функции, были два элемента в первом измерении @myarray. После использования функции defined количество элементов увеличивается до 3.

Как использовать функцию defined с добавлением новых элементов?

ответ

7

Сначала проверьте, существует ли ссылка на первый уровень.

if (defined($mylist[2]) && defined($mylist[2][0])) { 
    print "TRUE\n"; 
} 

Что вы столкнулись называется autovivification: при некоторых обстоятельствах, Perl создает сложные структуры данных, когда вы используете их, как будто они уже существовали.

3

Когда вы ссылаетесь на $mylist[2][0], perl's autovivification создает элемент массива $mylist[2].

Чтобы предотвратить это, вы можете проверить этот элемент первым:

if ((defined $mylist[2]) && (defined $mylist[2][0])) 
2

На самом деле, потому что это autovivification, вы можете проверить это легко с помощью Data :: Dumper, до и после использования определены.

use Data::Dumper; 
my @mylist; 

$mylist[0][0]="wqeqwe"; 
$mylist[0][1]="afasf"; 
$mylist[1][0]="lkkjh"; 

print Dumper(@mylist); 

Выход перед тем

$VAR1 = ['wqeqwe', 'afasf']; 
$VAR2 = [ 'lkkjh']; 


print Dumper(@mylist); 

Выход после

$VAR1 = [ 'wqeqwe','afasf' ]; 
$VAR2 = ['lkkjh']; 
$VAR3 = []; 
+1

Вы должны использовать ссылку в качестве аргумента для 'Dumper', например. 'print Dumper \ @ mylist'. Он сохранит структуру массива без изменений и сделает ее более читаемой. (Вы также должны отформатировать свой ответ, чтобы мы могли видеть структуру.) – TLP

3
defined($mylist[2][0]) 

эквивалентно

defined($mylist[2]->[0]) 

, который является коротким для

defined(($mylist[2] //= [])->[0]) 

вследствие автообнаружения. Вы можете отключить автовивитацию, используя прагму autovivification.

no autovivificatoin; 
if (defined($mylist[2][0])) 

Или вы можете избежать оценки кода, который может вызвать его.

if (defined($mylist[2]) && defined($mylist[2][0])) 
+1

Это действительно отстой, что средство проверки орфографии не распознает «автовивитацию», потому что так легко ошибаться! :) – ikegami

+0

Просто любопытно: если 'defined (mylist [2] [0])' добавляет новый элемент [autovivification] (http://search.cpan.org/perldoc?autovivification), почему это не заявление печати после ' defined (mylist [2] [0]) 'return' TRUE'? – 384X21

+3

@ user1029725 'defined ($ mylist [2] [0])' создает элемент '$ mylist [2]'. '$ mylist [2] [0]' все еще не определено. Вы можете проверить, чтобы убедиться, что с Data :: Dumper вы хотите. – Tim

5

Интересно отметить, что есть непрофильный Прагма называется autovivification, и что при запуске кода под no autovivification; ваша проблема исчезнет.

 Смежные вопросы

  • Нет связанных вопросов^_^