5

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?

Alan Haggai Alavi
  • 72,802
  • 19
  • 102
  • 127
CheeseConQueso
  • 5,831
  • 29
  • 93
  • 126

2 Answers2

21

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.)

cjm
  • 61,471
  • 9
  • 126
  • 175
  • 1
    thanks a bunch. this really helped me a lot rather than just provide one solution – CheeseConQueso Apr 11 '11 at 15:20
  • 1
    the selectall_arrayref method worked great. i never knew about that function/method of `DBI` and it looks like it will be very handy in the future – CheeseConQueso Apr 11 '11 at 15:23
  • what's the difference between passing `undef` and leaving `\%attr` out? – CheeseConQueso Apr 13 '11 at 18:45
  • @CheeseConQueso, if you leave `\%attr` out, then the first parameter in `@_` will be treated as `\%attr`. You can pass an empty hashref instead of `undef`, but you _must_ pass something for `\%attr` if you want to bind placeholders. – cjm Apr 13 '11 at 18:51
  • gotcha... that makes sense. They should re-word this or mention what you said in http://search.cpan.org/~timb/DBI-1.616/DBI.pm#General_Interface_Rules_&_Caveats - it says `In general, you can ignore \%attr parameters or pass it as undef.` – CheeseConQueso Apr 13 '11 at 18:56
  • @cjm Nice solution I wasn't even looking for this but it's pretty cool +1 – Alos Dec 30 '11 at 14:07
10

The problem is with the declaration of @ctc_rec and $i. Try this and your code should stop giving the error from strict:

Replace:

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

With:

my @ctc_rec;
my $i = 0;
odrm
  • 5,149
  • 1
  • 18
  • 13