#arrays #perl #multidimensional-array #strict
#массивы #perl #многомерный массив #строгий
Вопрос:
У меня есть пара строк кода, которые работают, если use strict;
закомментировано. Однако я не хочу отключать ее для всего скрипта только из-за одного небольшого раздела.
Мне нужно либо перекодировать ее, либо каким-то образом временно отключить use strict;
, а затем снова включить. Первый вариант более реалистичен, но я не знаю, как изменить код для работы в строгом режиме.
my ($ctc_rec_ref) = get_expected_contacts($ctc,$fy);
my @expected_ctc_rec = @$ctc_rec_ref;
print $expected_ctc_rec[0][0]."n";
print $expected_ctc_rec[0][1]."n";
print $expected_ctc_rec[0][2]."n";
sub get_expected_contacts
{
my (@ctc_rec,$i) = ((),0);
$STMT = "SELECT DISTINCT field1, field2, field3 FROM table WHERE field4 = ? AND field5 = ? AND field6 = 'E'";
$sth = $db1->prepare($STMT); $sth->execute(@_);
while(@results = $sth->fetchrow_array())
{
push @{ $ctc_rec[$i] }, $results[0];
push @{ $ctc_rec[$i] }, $results[1];
push @{ $ctc_rec[$i] }, $results[2];
$i ;
}
return (@ctc_rec);
}
При use strict;
включенном:
Не удается использовать string («0») в качестве ссылки на МАССИВ, пока «strict refs» используется в ./return5.pl строка 49.
(строка 49: push @{ $ctc_rec[$i] }, $results[0];
)
С use strict;
отключенным:
1468778
04/01/2011
30557
Как я могу переписать этот код, чтобы он работал так, как если бы строгий режим был отключен? Если это невозможно, можно use strict;
временно отключить, а затем снова включить для этого короткого фрагмента кода в скрипте?
Ответ №1:
Проблема в том, что
my (@ctc_rec,$i) = ((),0);
делает не то, что вы думаете. Это означает то же самое, что
my @ctc_rec = (0);
my $i;
strict
делает то, для чего предназначено, и улавливает вашу ошибку. Попробуйте написать:
my @ctc_rec;
my $i = 0;
вместо этого. Это должно устранить ошибку.
В этом случае есть другой способ избавиться от ошибки и одновременно значительно упростить свой код: используйте selectall_arrayref .
sub get_expected_contacts
{
return $db1->selectall_arrayref(
"SELECT DISTINCT field1, field2, field3 FROM table WHERE field4 = ? AND field5 = ? AND field6 = 'E'",
undef, @_
);
}
Если вы действительно намеренно делали что-то, что было запрещено strict
(но знали, что делаете), вы можете отключить strict
локально:
use strict;
# this code is strict
{
no strict;
# some code that is not strict here
}
# strict is back in effect now
Но вы никогда не должны этого делать, пока не поймете точно, на что strict
жалуется, и почему это нормально делать в данном случае. Также лучше отключить только ту часть strict
, которая вам необходима. Например, вы можете сказать, no strict 'refs';
чтобы разрешить символические ссылки, не отключая другие действия strict
. (Примечание: тот же метод работает с прагмой warnings, которую вы также должны использовать.)
Комментарии:
1. большое спасибо. это действительно очень помогло мне, а не просто предоставить одно решение
2. метод selectall_arrayref отлично сработал. я никогда не знал об этой функции / методе
DBI
и, похоже, это будет очень удобно в будущем3. в чем разница между передачей
undef
и пропуском%attr
?4. @CheeseConQueso, если вы оставите
%attr
в стороне, то первый параметр в@_
будет обрабатываться как%attr
. Вы можете передать пустой hashref вместоundef
, но вы должны передать что-то для%attr
, если хотите привязать заполнители.5. понял … это имеет смысл. Они должны переписать это или упомянуть то, что вы сказали в search.cpan.org / ~ timb / DBI-1.616 / … — в нем говорится
In general, you can ignore %attr parameters or pass it as undef.
Ответ №2:
Проблема связана с объявлением @ctc_rec и $ i. Попробуйте это, и ваш код перестанет выдавать ошибку из strict:
Заменить:
my (@ctc_rec,$i) = ((),0);
С:
my @ctc_rec;
my $i = 0;
Комментарии:
1. спасибо — хотя вы сначала ответили рабочим решением, cjm дал мне гораздо больше для рассмотрения и работы.