in reply to Re: Hash syntax
in thread Hash syntax

Hello Monks,

The several answers are spot-on, including encouraging the writer to use the debugger, but I have a curious issue that is somewhat related, to wit: for my amusement I've written three great circle calculators (Spherical Law of Cosines, Haversine and Vincenty Inverse; C, Perl and Python versions) that stores airport locations and their geodesic parameters (latitude and longitude) in a Btree BerkeleyDB. The hash instances are tied with MLDBM. I load them into the DB from a tab-delimited file. Here is my airport hash definition:

$APref->{++$id} = { APname => $loc, geodesics => [ $lat, $long, dms2rad($lat), dms2rad($long) ] };

$APref is a hash reference. The key is an interger rather than a location string so I can say, for example; calculate the GC distance between 17 and 33. When I access that array, as in when printing out a list or passing two airport instances to my GC calculators I would like to say:

$APref->{$key}{geodesics}->[0..3]

but this causes Perl (5.38.2) to barf. This expression

@{$APref->{$key}{geodesics}}[0..3]

is the only way to fetch that slice. My standard rule is to use the arrow operator wherever there is a reference in such an expression, but the block indirection version is the only syntax that works, in this case. Is their something about taking an array slice that defeats the arrow operator, or am I missing something? I have no problem using or understanding that noisier indirection syntax, but there must be an explanation beyond my current understanding of the arrow operator. Thoughts please?

U P D A T E

Thank you LanX and tybalt89. You're never too old to learn something you didn't know about Perl.

->@[0..3]

is exactly what I was looking for, and context is everything; a slice is not a scalar.

Replies are listed 'Best First'.
Re^3: Hash syntax
by tybalt89 (Monsignor) on Aug 25, 2024 at 23:29 UTC
    $APref->{$key}{geodesics}->@[0..3]

    Close enough?

Re^3: Hash syntax (slice from arrayref)
by LanX (Saint) on Aug 26, 2024 at 00:54 UTC
    This should be a proper thread, I considered that it's moved into one.

    > I have no problem using or understanding that noisier indirection syntax, but there must be an explanation beyond my current understanding of the arrow operator. Thoughts please?

    Short answer

    Symmetry!

    $arr_ref->[@slice] doesn't "work" because the analog $arr[@slice] also doesn't do what you mean.

    NB: @arr[@slice] is different.

    Long answer

    Perl is pretty consistent that $ means scalar and @ means a list. The whole context rules depend on it. Something like $ref->[@slice] is as misleading as $arr[@slice] because a scalar has to be returned. (What's happening here is that the scalar value of @slice is calculated instead of a list)

    For a slice the correct syntax is @arr[@slice]

    Compare the analogy

    DB<12> @a = "a".."z"; $ar = \@a DB<13> p $ar->[1], $a[1] bb DB<14> @slice = 1..3 DB<15> p $ar->[@slice], $a[@slice] dd DB<16> p $ar->@[@slice], @a[@slice] bcdbcd DB<17> p @$ar[@slice], @a[@slice] bcdbcd

    The deref syntax in line 16 is newer and was introduced to avoid @{...} constructs like in line 17 (In this case the brackets are optional)

    What you are suggesting would break the symmetry and cause confusion and bugs.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

    Updates

    Added short answer