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.
-
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)}
-
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}
-
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}
-
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.
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. | [reply] [d/l] [select] |
|
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")
| [reply] |
|
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.
---
demerphq
<Elian> And I do take a kind of perverse pleasure in having an OO assembly language...
| [reply] [d/l] |
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 :-)
Chris
M-x auto-bs-mode | [reply] [d/l] [select] |
|
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")
| [reply] [d/l] [select] |
|
| [reply] |
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.
| [reply] |
Re: References quick reference
by ixolit (Novice) on Feb 08, 2008 at 18:27 UTC
|
Wonderful article, thank you | [reply] |
Re: References quick reference
by fedekiller (Initiate) on Dec 12, 2006 at 22:20 UTC
|
Very nice, i found this very ufseul :)
Thanks! | [reply] |
|
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?
| [reply] |
|
Hello buchi2,
On the subject of complex data structures in Perl, be sure to read perllol and, especially, perldsc.
Hope that helps,
| [reply] |
|
|
|