Search code examples
arraysperlmultidimensional-arraystrict

How can I avoid this error produced while using 'strict'?


I have a couple of lines of code that work if use strict; is commented out. However, I don't want to have it disabled for the entire script just because of one small section.

I need to either recode it, or somehow disable use strict; temporarily and then re-enable it. The first option is more realistic, but I don't know how to change the code to work in strict mode.

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);
}


With use strict; enabled:

Can't use string ("0") as an ARRAY ref while "strict refs" in use at ./return5.pl line 49.

(line 49: push @{ $ctc_rec[$i] }, $results[0];)


With use strict; disabled:

1468778 
04/01/2011 
30557

How can I rewrite this code so that it works as if strict mode was disabled? If that is not possible, can use strict; be temporarily disabled and then re-enabled for this short piece of code within the script?


Solution

  • The problem is that

    my (@ctc_rec,$i) = ((),0);
    

    doesn't do what you think it does. It means the same as

    my @ctc_rec = (0);
    my $i;
    

    strict is doing what it's meant to and catching your mistake. Try writing:

    my @ctc_rec;
    my $i = 0;
    

    instead. That should get rid of the error.

    In this case, there's another way to get rid of the error, and simplify your code considerably at the same time: use 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, @_
       );
    }
    

    If you really were intentionally doing something that was prohibited by strict (but knew what you were doing), you can disable strict locally:

    use strict;
    
    # this code is strict
    { 
      no strict;
      # some code that is not strict here
    }
    # strict is back in effect now
    

    But you should never do that until you understand exactly what strict is complaining about, and why it's ok to do that in this instance. It's also better to disable only the part of strict that you have to. For instance, you can say no strict 'refs'; to allow symbolic references without disabling the other things strict does. (Note: The same technique works with the warnings pragma, which you should also be using.)