Problem with syntax getting array elements

Discussion in 'Perl Misc' started by Dave Saville, Jun 6, 2012.

  1. Dave Saville

    Dave Saville Guest

    Given

    my @x = qw(a b c);
    print "$x[2]\n";
    ($a, $b) = @x[1,2];
    print "$a $b\n";

    Gives me

    c
    b c

    But

    my %h;
    $h{a} = [1,2,3];
    print $h{a}[2]."\n";
    my ($a, $b) = $h{a}[1,2];
    print "$a $b\n";

    Gives

    3
    Use of uninitialized value $b in concatenation (.) or string
    3

    I have tried all sorts of brackets braces etc. in various combinations
    but I cannot get the anonymous array contained in the hash to work
    like the first example. What silly thing am I missing?

    TIA
    --
    Regards
    Dave Saville
    Dave Saville, Jun 6, 2012
    #1
    1. Advertising

  2. Dave Saville

    Tim Watts Guest

    Dave Saville wrote:

    > Given
    >
    > my @x = qw(a b c);
    > print "$x[2]\n";
    > ($a, $b) = @x[1,2];
    > print "$a $b\n";
    >
    > Gives me
    >
    > c
    > b c
    >
    > But
    >
    > my %h;
    > $h{a} = [1,2,3];
    > print $h{a}[2]."\n";
    > my ($a, $b) = $h{a}[1,2];
    > print "$a $b\n";
    >
    > Gives
    >
    > 3
    > Use of uninitialized value $b in concatenation (.) or string
    > 3
    >
    > I have tried all sorts of brackets braces etc. in various combinations
    > but I cannot get the anonymous array contained in the hash to work
    > like the first example. What silly thing am I missing?
    >
    > TIA


    my %h;
    $h{a} = [1,2,3];
    print $h{a}->[2]."\n"; #[1]
    my ($a, $b) = @{$h{a}}[1,2]; #[2]
    print "$a $b\n";

    [1] As the value of $h{a} is an array ref, not an array, I prefer to use the
    deref operator -> for clarity.

    [2] This defrefs the arrayref explicitly.

    I am not a syntax master so I will not attempt to explain the ins and outs,
    but the above works I think as you intended...

    HTH

    Tim

    --
    Tim Watts
    Tim Watts, Jun 6, 2012
    #2
    1. Advertising

  3. Dave Saville

    Dave Saville Guest

    On Wed, 6 Jun 2012 09:01:26 UTC, Tim Watts <>
    wrote:

    <snip>
    > [1] As the value of $h{a} is an array ref, not an array, I prefer to use the
    > deref operator -> for clarity.
    >
    > [2] This defrefs the arrayref explicitly.
    >
    > I am not a syntax master so I will not attempt to explain the ins and outs,
    > but the above works I think as you intended...


    Thank you very much. I had tried -> but not the same way. I knew it
    was something like that but could not figure it out nor find any
    helpful example.
    --
    Regards
    Dave Saville
    Dave Saville, Jun 6, 2012
    #3
  4. Dave Saville

    Uri Guttman Guest

    >>>>> "DS" == Dave Saville <> writes:

    DS> On Wed, 6 Jun 2012 09:01:26 UTC, Tim Watts <>
    DS> wrote:

    DS> <snip>
    >> [1] As the value of $h{a} is an array ref, not an array, I prefer to use the
    >> deref operator -> for clarity.
    >>
    >> [2] This defrefs the arrayref explicitly.
    >>
    >> I am not a syntax master so I will not attempt to explain the ins and outs,
    >> but the above works I think as you intended...


    DS> Thank you very much. I had tried -> but not the same way. I knew it
    DS> was something like that but could not figure it out nor find any
    DS> helpful example.

    you use -> to get only one element from a ref. it is clearer to use ->
    for this purpose. when you want to slice (getting multiple elements) you
    must do a full deref of the ref with @{} or %{} followed by the normal
    slice index (e.g. [1, 2]).

    uri
    Uri Guttman, Jun 6, 2012
    #4
  5. "Dave Saville" <> writes:
    > my %h;
    > $h{a} = [1,2,3];
    > print $h{a}[2]."\n";
    > my ($a, $b) = $h{a}[1,2];


    The reason why this doesn't work is because the expression inside the
    subscript ([]) is evaluated in scalar context in this case,
    consequently, it's a comma-operator expression whose value is 2. In
    order to denote a slice, a @ is needed in here.

    $h{a}[1,2]

    is 'syntactic sugar' for

    $h{a}->[1,2]

    which is, in turn, syntactic sugar for

    ${$h{a}}[1,2]

    but since you want an array slice, it should be
    (as Tim Watts already posted)

    @{$h{a}}[1,2]

    {{$h{a}} being a block which returns a reference of 'a suitable type'
    for this expression.

    If being unsure how perl 'sees' a specific expression, the Deparse
    module can sometimes be helpful. For your code above, the output (perl
    -MO=Deparse) is

    my %h;
    $h{'a'} = [1, 2, 3];
    print $h{'a'}[2] . "\n";
    my($a, $b) = $h{'a'}['???', 2];
    print "$a $b\n";
    Rainer Weikusat, Jun 6, 2012
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. diffused
    Replies:
    9
    Views:
    722
    Oscar kind
    Aug 1, 2004
  2. Shalini
    Replies:
    2
    Views:
    495
    Brian Genisio
    Jan 9, 2004
  3. P
    Replies:
    1
    Views:
    1,155
    Joe Kesselman
    Jul 7, 2006
  4. Victor Reyes
    Replies:
    5
    Views:
    128
    Victor Reyes
    Apr 30, 2008
  5. sam

    getting array elements

    sam, Dec 24, 2004, in forum: Perl Misc
    Replies:
    9
    Views:
    88
    Chris Mattern
    Dec 28, 2004
Loading...

Share This Page