Как я могу избежать этой ошибки, возникающей при использовании ‘strict’?

#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 дал мне гораздо больше для рассмотрения и работы.