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

Hi, I have the following data structure:

my @AnData; my %AN=(data => \@AnData);

Now if I want to reference an element of the array @AnData via the hash %AN, I found by trial and error that I have to use: \$AN{data}[0x16]

Why do I need the extra backslash there?

I would have thought that $AN{data}[0x16] would already be a reference to the element 16 of array @AnData, as $AN{data} is a reference to the array @AnData. To access the value I would have expected to have to use: $$AN{data}[0x16] instead of $AN{data}[0x16].

Thanks in advance for any clarification.
A confused perltux

Replies are listed 'Best First'.
Re: complex data structures
by haukex (Archbishop) on Sep 23, 2016 at 06:33 UTC

    Hi perltux,

    Now if I want to reference ... To access the value

    I think the terminology you're using is confusing the issue a bit. Could you explain with code what you are trying to do? It would also be very useful if you could show your data structure via Data::Dumper or Data::Dump.

    When you say $AN{data}[0x16], %AN is of course a hash, in which the value $AN{data} is a reference to an array, and you are then indexing that array with the subscript [0x16] (which, as tybalt89 already pointed out, is actually the 23rd element of the array at index 22). The only reference at this point is the one stored at $AN{data}, which is the reference to the array. Note that $AN{data}[0x16] is the same thing as $AN{data}->[0x16], where -> is the arrow (dereference) operator, which is implied and optional between bracketed subscripts.

    You access the value stored at $AN{data}[0x16] with, for example, my $x = $AN{data}[0x16]; and set the value with $AN{data}[0x16] = $x;. That much should be obvious, but that value may also be a reference:

    If you want $AN{data}[0x16] to store a reference to something else, then for example you need to say something like my $val = 123; $AN{data}[0x16] = \$val;. Then $AN{data}[0x16] contains a reference to the scalar $val and you dereference that reference with ${ $AN{data}[0x16] }, so ${ $AN{data}[0x16] } = 456; will actually set $val to 456. Another example is my @foo = qw/a b c/; $AN{data}[0x17] = \@foo;, in which case you can access that array using the implicit dereferencing mentioned above, so $AN{data}[0x17][2] accesses the value that is currently "c".

    Note that the syntax $$AN{data}[0x16] means something else: it dereferences a hash reference named $AN - think of it as ${$AN} {data}[0x16] or $AN->{data}->[0x16].

    On the other hand, if you want to take a reference to $AN{data}[0x16], you can say my $r = \$AN{data}[0x16];, now $r holds a reference to that element of the data structure. You can access that element of the data structure (get and set the value of $AN{data}[0x16]) with $$r.

    I recommend you read perlreftut, perlref, and perldsc - that gives you just about everything you need to know about references in Perl.

    Hope this helps,
    -- Hauke D

    Made few updates to wording and a few additions

Re: complex data structures
by tybalt89 (Monsignor) on Sep 23, 2016 at 02:12 UTC
    #!/usr/bin/perl -l # http://perlmonks.org/?node_id=1172399 use strict; use warnings; my @AnData = 'A'..'Z'; my %AN=(data => \@AnData); print $AN{data}[0x16], ' ', $AN{data}[22];

    prints:

    W W

    Note that 0x16 is the same as 22.

      Thanks for pointing that out, but that was just a copy and paste mistake, not what my actual question is about.

        I think he meant to demonstrate that you do not need \$ (or $$) to access the data you have described. However, if you want to create a reference to that single piece of data then you do indeed have to use the prefix \ because that's exactly what that prefix does.

        There are also other ways to create references to data, such as {} and []. References are described in perldoc perlref

        If this does not answer your question, maybe you need to provide a little more context to help us understand why this does not solve your problem?

        -- FloydATC

        Time flies when you don't know what you're doing

        I thought your actual question was about a \.

        Please note my print statement does not need the \ to work correctly.

        Perhaps I am misunderstanding your question. Please provide an actual runnable program that shows a failure when the \ is not used, and success when the \ is used, and we can proceed from there.