Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

References quick reference

by tye (Sage)
on Apr 05, 2001 at 02:39 UTC ( [id://69927]=perltutorial: print w/replies, xml ) Need Help??

I find that the following 4 simple rules cover all of the ways to dereference data structure references. Having the rules spelled out so simply has made using references much less confusing to me.

  1. To use a reference, say $ref, you put {$ref} in place of a variable name ( not counting the $, %, or @ ). That is, replace the variable name with the reference enclosed in braces:
    $scalar ${$sRef} @array @{$aRef} $array[0] ${$aRef}[0] $#array $#{$aRef} %hash %{$hRef} $hash{KEY} ${$hRef}{KEY} @hash{@list} @{$hRef}{@list}
    Note that this works for any expression that returns a reference, not just the simple examples above:
    ${$sRefs[0]} ${$sRefs{key}} ${getScalarRef()} @{$aRefs[0]} @{$aRefs{key}} @{getArrayRef()} %{$hRefs[0]} %{$hRefs{key}} %{getHashRef()} @{ $bool ? \%hash1 : \%hash2 }{qw(some keys)}
  2. If the reference is held in a simple scalar variable, then the braces, { and }, can be dropped:
    $scalar $$sRef @array @$aRef $array[0] $$aRef[0] $#array $#$aRef %hash %$hRef $hash{KEY} $$hRef{KEY} @hash{@list} @$hRef{@list}
  3. If you are getting a scalar from a hash or an array, then you can replace ${$ref} with $ref->:
    $array[0] ${$aRef}[0] $aRef->[0] $hash{KEY} ${$hRef}{KEY} $hRef->{KEY}
  4. If the reference is in a hash or an array (and you are getting back a scalar), then you can drop the -> between the adjacent [0] and/or {KEY} parts:
    ${$aRef->[0]}[1] $aRef->[0]->[1] $aRef->[0][1] ${$aRef->[0]}{KEY} $aRef->[0]->{KEY} $aRef->[0]{KEY} ${$hRef->{KEY}}[1] $hRef->{KEY}->[1] $hRef->{KEY}[1] ${$hRef->{A}}{B} $hRef->{A}->{B} $hRef->{A}{B}

I hope others find this as helpful as I have.

Thanks to arturo for suggesting that I turn references quick reference (Re: push) into a tutorial.

        - tye (but my friends call me "Tye")

Thanks to kutsu for pointing out that I've had ${hRef}{KEY} instead of ${$hRef}{KEY} for all these years.

Replies are listed 'Best First'.
Re (tilly) 1: References quick reference
by tilly (Archbishop) on Apr 05, 2001 at 08:46 UTC
    Well done, but you have omitted the fact that dereferencing an anonymous function means calling it:
    &$aSub(@args); $aSub->(@args); # This notation due to merlyn
    and at this point if people wonder why a method call looks like a dereferencing operation, they should give themselves brownie points because it is. When you call bless on a reference, it is not the reference that is blessed, it is the thing that the reference points at. And a method call is really a matter of dereferencing the reference in a way that is looking for a method. Consider:
    package foo; sub bar { print "foobar strikes again!\n"; } package main; # Create and throw away an object bless \$x, "foo"; # But the blessing is not forgotten! (\$x)->bar();
    This detail was pointed out to me by merlyn in chatter about a week ago. At first it surprised me, but then I thought about it and it made a lot of sense. After all if I have 10 references to the same thing, shouldn't dereferencing any of them be equivalent? Doesn't a method call look like just dereferencing...?

    And so to your list you can add calling an anonymous subroutine and making a method call as dereferencing operations.

      you have omitted the fact that dereferencing an anonymous function

      Quite intentionally. I didn't want to distract from the topic: dereferencing "data structure references". I wanted people to be able to let that sink in and then never worry about it again. Perhaps a title change is in order, though I don't want a title that will scare people off either. (:

      Had I chosen to cover code references, then I would have been more detailed than what you've discussed above. I started to and then realized I didn't have handy the details required to cover that topic in a manner deserving of the label "tutorial" (and also realized that it didn't fit in anyway).

      I also didn't talk about creating references, symbolic references, blessed references, closures, ref, UNIVERSAL::isa(), references to globs, to the IO chunks of globs, to compiled regular expressions, nor to any other types of things that Perl lets you have a reference to.

      All of those break some of the above rules and discussing them would distract the reader from once and for all getting those rules down. I also lump data structure references together in my head while thinking of code references separately from glob references separately from...

      So, no, I'm not going to add your two things to my list. q-:

              - tye (but my friends call me "Tye")

      dereferencing an anonymous function

      Just to clarify, its not a question of anonymous functions (unless your definition of anonymous is the same as "reference to a"). Any valid reference to a function can be called as you say.


      <Elian> And I do take a kind of perverse pleasure in having an OO assembly language...
Re: References quick reference
by lachoy (Parson) on Apr 05, 2001 at 03:46 UTC

    Great summary. Personally, I find the following:

    @{$aRefs[0]} @{$aRefs{key}} @{getArrayRef()} %{$hRefs[0]} %{$hRefs{key}} %{getHashRef()}

    much cleaner and easier to read than:

    @array @$aRef %hash %$hRef $array[0] $$aref[0] $hash{KEY} $$href{KEY}

    Maybe it's just me, but I've been using perl for 4+ years and I have never liked stringing the variable characters one after the other (%$). Particularly epxressions like the third and fourth line in the second group above.

    I've always thought that using the @{ } %{ } syntax more clearly and consistently evoked what I'm trying to say -- you can use it with variables, method calls/subroutines, etc. I'm interested if other folks feel differently -- it seems to be a matter of taste rather than an opportunity to define yet another One True Way :-)

    M-x auto-bs-mode

      I definitely avoid $$hRef{key} and $$aRef[0] (using $hRef->{key} instead). But I don't really like @{...} much (too hard to match up the open and close braces) so I prefer @$aRef and %$hRef to the versions with {}. For @{$aRefs{key}} I have no choice.

      But when (and if) a version of Perl comes out with "the patch" applied, I'll be switching to nearly exclusively using -> to deference. This patch allows $aRef->@, $hRef->%, $aRef->@[1..5], etc. which are particularly nice for cases like $aRefs->{key}->[0]->getList()->@[2..6].

              - tye (but my friends call me "Tye")
      Very good...
Re: References quick reference
by Anonymous Monk on Nov 04, 2005 at 09:22 UTC
    brilliant. thank you so much for this! I'm a newbie and love php. I was starting to hate perl for all it's complicated syntax, especially with references, but this makes it clear. tar.
Re: References quick reference
by ixolit (Novice) on Feb 08, 2008 at 18:27 UTC
    Wonderful article, thank you
Re: References quick reference
by fedekiller (Initiate) on Dec 12, 2006 at 22:20 UTC
    Very nice, i found this very ufseul :) Thanks!
      Very helpfull, thanx. :)
      Perhaps adding examples for more complex structures? Hashes of arrays and so on and perhaps how to put it in, how to get it out, how to pass it into sub?

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perltutorial [id://69927]
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-06-21 03:42 GMT
Find Nodes?
    Voting Booth?

    No recent polls found

    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.