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

Hello- I have the following in my code:
my %hash; $hash{"one"} = [[1,2,3],[]];
When i try to access the first element of the array, which is [1,2,3] and print its contents, i'm surprised that the following works without generating a warning:
print @{@{$hash{"one"}}[0]}, "\n";
and produces the correct output: 123
I thought that perl would generate a warning and require that i use:
print @{${$hash{"one"}}[0]}, "\n";
That is because when i use:
my @array = (4,5,6); print @array[0];
a warning message is generated and tells me that @array[0] better be written as $array[0]; Why is it not generating the warning in the first case?
Thanks a lot in advance,

Replies are listed 'Best First'.
Re: accessing array elements using a reference
by samtregar (Abbot) on May 19, 2008 at 03:55 UTC
    It seems that Perl figures that if you know enough to use references then you must know enough to pick the sigil you wanted. The warning doesn't seem to be triggered any time there's a reference involved.

    I suppose you might reasonably call this a bug. Want to try to fix it? Start by reading perlhack!

    -sam

      Thanks for your reply. I would like to note that even when a warning is generated when i use @array[0], the output is the same as when i use what perl suggests i.e. $array[0].
      So both ways @array[0] vs $array[0] produce the same result but the former generates a warning.

        @array[0] and $array[0] are very similar. In fact, in scalar context, they evaluate to the same thing. warnings aside, there are two differences between slices and indexed elements. First, the index expression for the slice is evaluated in list context while the index expression for the element is evaluated in scalar context. Second, the slice creates a list context when used as an lvalue while the element creates a scalar context.

Re: accessing array elements using a reference
by grizzley (Chaplain) on May 19, 2008 at 09:53 UTC
    You have two different pieces of code and that's why the behaviour is different. @{${$hash{"one"}}[0]} returns an array, not reference to an array:
    $hash{"one"} -> [[1,2,3],[]] @{$hash{"one"}} -> ([1,2,3],[]) ${$hash{"one"}}[0] -> [1,2,3] @{${$hash{"one"}}[0]} -> (1,2,3)
      Yes but why @{$hash{"one"}}[0] does not generate a warning while @array[0] does?
        My fault, I copied wrong code for testing and didn't understand the question. But I think BrowserUk has a good answer for you.