mosh has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks !

I've got impossible error from Perl:
"Can't use string ("string") as a HASH ref while "strict refs" in use at C:\... line 1190"

What the heck should be this error ?

I searched the Web, and here what I got:
code 1:

#!/usr/bin/perl -w use strict; sub showArray(\@) { my(@arr) = @{(shift)}; my($temp); foreach $temp (@arr) { print "$temp\n"; } } sub higherLevel(\@) { my(@arr) = @{(shift)}; showArray(@arr); } my(@arr) = ("one","two","three"); higherLevel(@arr);

Code 2:

#!/usr/bin/perl -w use strict; sub higherLevel(\@) { my(@arr) = @{(shift)}; showArray(@arr); } sub showArray(\@) { my(@arr) = @{(shift)}; my($temp); foreach $temp (@arr) { print "$temp\n"; } } my(@arr) = ("one","two","three"); higherLevel(@arr);

The first code went great, but the second returned the previous error !
I do not understand, the two sections are the same !!!
What the heck is going on?
Mosh.

Replies are listed 'Best First'.
Re: a HASH ref while "strict refs" ERROR
by ikegami (Patriarch) on May 04, 2005 at 17:34 UTC

    In the second, showArray(@arr) appears before the prototype for showArray is known, so the prototype is ignored. In the first, showArray(@arr) becomes showArray(\@arr), but there's no change in the second snippet. Yet another reason to avoid prototypes. The following is a solution that's no less efficient and doesn't exhibit the problem regardless of the order in which the functions are defined:

    #!/usr/bin/perl -w use strict; sub higherLevel { my(@arr) = @{(shift)}; showArray(\@arr); } sub showArray { my(@arr) = @{(shift)}; my($temp); foreach $temp (@arr) { print "$temp\n"; } } my(@arr) = ("one","two","three"); higherLevel(\@arr);
      Considering that the first thing each sub does is copy all the elements of the array, there's not much point in passing a ref and dereferencing it. Just sling the arrays around.
      sub higherLevel { my(@arr) = @_; showArray(@arr); } sub showArray { my(@arr) = @_; foreach my $temp (@arr) { print "$temp\n"; } } my(@arr) = ("one","two","three"); higherLevel(@arr);

      Caution: Contents may have been coded under pressure.

        You're right

        sub test_arr { my @arr = @_; $a = join('|', @arr); } sub test_ref { my @arr = @{$_[0]}; $a = join('|', @arr); } sub test_ref2 { $a = join('|', @_); }
        TINY ARRAY Rate ref arr ref2 ref 120870/s -- -14% -17% arr 140004/s 16% -- -4% ref2 145146/s 20% 4% -- SMALL ARRAY Rate ref arr ref2 ref 61587/s -- -8% -58% arr 67214/s 9% -- -54% ref2 146895/s 139% 119% -- GIANT ARRAY Rate ref arr ref2 ref 850/s -- -0% -99% arr 850/s 0% -- -99% ref2 148539/s 17383% 17381% --

        The arrays would have to be pretty damn big for it to matter if one does my @arr = @_.

Re: a HASH ref while "strict refs" ERROR
by Paladin (Vicar) on May 04, 2005 at 17:39 UTC

    Another way to fix the problem if you do really want to use prototypes is to declare them before you use them (although I do agree with ikegami that it is probably better not to use them in the first place):

    use strict; sub higherLevel(\@); sub showArray(\@); sub higherLevel(\@) { my(@arr) = @{(shift)}; showArray(@arr); } sub showArray(\@) { my(@arr) = @{(shift)}; my($temp); foreach $temp (@arr) { print "$temp\n"; } } my(@arr) = ("one","two","three"); higherLevel(@arr);