Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Indirection in a hash

Reply
Thread Tools

Indirection in a hash

 
 
dn.perl@gmail.com
Guest
Posts: n/a
 
      10-22-2009

Here is a piece of code whose output is : 'miami21 and miami21' :

#!/usr/bin/perl

use strict ;

my %hash = () ;

push @{$hash{florida}}, 'miami', 'miami01', 'miami02' ;
push @{$hash{florida}}, 'miami', 'miami21', 'miami22' ;

my $name = ${$hash{florida}}[4] . " and " . $hash{florida}[4] ;
print "name = $name \n" ;


How are $hash{florida}[4] and ${$hash{florida}}[4] the same thing?
I would have expected that indirection (I hope that is the correct
word for it) to produce something unintelligible or something
meaningless.

TIA.

 
Reply With Quote
 
 
 
 
Paul Lalli
Guest
Posts: n/a
 
      10-22-2009
On Oct 22, 12:12*pm, "dn.p...@gmail.com" <dn.p...@gmail.com> wrote:
> How are $hash{florida}[4] *and *${$hash{florida}}[4] *the same thing?
> I would have expected that indirection (I hope that is the correct
> word for it) to produce something unintelligible or something
> meaningless.


%hash is a hash.

$hash{florida} is a reference to an array.

@{$hash{florida}} is the array that $hash{$forida} references

${$hash{florida}}[4] is the 5th element of the array @{$hash{florida}}

$hash{forida}->[4] is the alternative "arrow syntax" notation for the
5th element of the array @{$hash{florida}}

$hash{florida}[4] is the same syntax, taking advantage of the face
that when an arrow separates two bracket/braces, it can be dropped.


perldoc perlreftut's Use Rule #1 and Use Rule #2 would be very good
things for you to read.

Paul Lalli


 
Reply With Quote
 
 
 
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      10-22-2009
<> wrote:
> Here is a piece of code whose output is : 'miami21 and miami21' :


> #!/usr/bin/perl
> use strict ;
> my %hash = () ;
> push @{$hash{florida}}, 'miami', 'miami01', 'miami02' ;
> push @{$hash{florida}}, 'miami', 'miami21', 'miami22' ;
> my $name = ${$hash{florida}}[4] . " and " . $hash{florida}[4] ;
> print "name = $name \n" ;


> How are $hash{florida}[4] and ${$hash{florida}}[4] the same thing?
> I would have expected that indirection (I hope that is the correct
> word for it) to produce something unintelligible or something
> meaningless.


There's a special rule that '$hash{florida}[4]' is understood
to mean '$hash{florida}->[4]' and that's why you get the same
value as from '${hash{florida}}[4]'. The same holds if you have
a hash reference instead of an array reference, e.g. with

$hash{x} = { age => 7, name => 'Marvin };
print $hash{x}{age};

This will give you 7 since it's treated as if you had written
'$hash{x}->[age}' which is the same as ${$hash{x}}{age}'.

Or another example where there's a shortcut

$a = [ [ 1, 2, 3 ], [ 4, 6, 7 ] ];
print $b->[1][1];

will print 5 since it's taken to mean '$b->[1]->[1] or
${$b->[1]}[1]}' or '${$$b[1]}[1]' or '${${$b}[1]}[1]'

All this follows the same rule: the arrow operator is
optional between brackets and braces (or between a closing
bracket or brace and a paranthesis for an indirect function
call).

Most often it's probably used for "multidimensional arrays"
(I put that in parantheses since there aren't real multi-
dimensional arrays in Perl but instead you use arrays of
array references to emulate them). So when you have e.g.

@a = ( [ 1, 2, 3 ], [ 4, 5, 6 ] );

without that rule you would have to use one of

$a[1]->[1] or ${$a[1]}[1]

to get at the second element of the second array. But know
you can it write it instead as

$a[1][1]

which will make it look more like a normal multi-dimensional
array for people used to e.g. C.

Regards, Jens
--
\ Jens Thoms Toerring ___
\__________________________ http://toerring.de
 
Reply With Quote
 
C.DeRykus
Guest
Posts: n/a
 
      10-22-2009
On Oct 22, 9:12*am, "dn.p...@gmail.com" <dn.p...@gmail.com> wrote:
> Here is a piece of code whose output is : 'miami21 and miami21' :
>
> #!/usr/bin/perl
>
> use strict ;
>
> my %hash = () ;
>
> push @{$hash{florida}}, 'miami', 'miami01', 'miami02' ;
> push @{$hash{florida}}, 'miami', 'miami21', 'miami22' ;
>
> my $name = ${$hash{florida}}[4] . " and " . $hash{florida}[4] ;
> print "name = $name \n" ;
>
> How are $hash{florida}[4] *and *${$hash{florida}}[4] *the same thing?
> I would have expected that indirection (I hope that is the correct
> word for it) to produce something unintelligible or something
> meaningless.
>


If this had been a named array: you could just say:

push @array, ....
push @array, 'miami', 'miami21', 'miami22'

and later reference one of the array's members:

$array[4]


But with an anonymous array, you just need to replace the
named array with an anonymous ref you create on the fly:

push @{$hash{florida}}, 'miami', 'miami21', 'miami22'

And then later refer to the anonymous array member with:

${$hash{florida}}[4]


For details: perldoc perlref, perlreftut, and/or perldsc .

Data:umper can help with a peek under the covers too:

use Data:umper; ... etc; print Dumper \%hash;

--
Charles DeRykus
 
Reply With Quote
 
Mart van de Wege
Guest
Posts: n/a
 
      10-23-2009
(Jens Thoms Toerring) writes:

> "multidimensional arrays" (I put that in parantheses since there
> aren't real multi- dimensional arrays in Perl but instead you use
> arrays of array references to emulate them).


(ITYM quotes, not parentheses).

What is the difference? Surely this is the most obvious way to implement
multidimensional arrays on a lower level?

And if Perl's "array of references" is functionally equivalent to a
multidimensional array (and it is), then isn't it a multidimensional
array?

Mart

--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      10-23-2009
>>>>> "MvdW" == Mart van de Wege <> writes:

MvdW> (Jens Thoms Toerring) writes:
>> "multidimensional arrays" (I put that in parantheses since there
>> aren't real multi- dimensional arrays in Perl but instead you use
>> arrays of array references to emulate them).


MvdW> (ITYM quotes, not parentheses).

MvdW> What is the difference? Surely this is the most obvious way to implement
MvdW> multidimensional arrays on a lower level?

MvdW> And if Perl's "array of references" is functionally equivalent to a
MvdW> multidimensional array (and it is), then isn't it a multidimensional
MvdW> array?

by the ways classic compiled langs like c does them, then no, perl
doesn't support multidimensional arrays. in those langs you usually
predeclare all the array's dimensions and you can directly access
elements with a fast calculation of the correct offset given the
indices. in perl's version you have to loop over each dimension then
index to get the next level down. it is linear growth with the number of
dimensions so it is slower. the advantage of perl's design is that you
can mix and match arrays and hashes in such a data tree and create it
dynamically without knowing any dimensions in advance. this is worth the
extra cost in speed IMO as real world data is rarely fixed in dimensions
at compile time.

uri

--
Uri Guttman ------ -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      10-23-2009
Mart van de Wege <> wrote:
> (Jens Thoms Toerring) writes:
>
>> "multidimensional arrays" (I put that in parantheses since there
>> aren't real multi- dimensional arrays in Perl but instead you use
>> arrays of array references to emulate them).

>
>(ITYM quotes, not parentheses).
>
>What is the difference? Surely this is the most obvious way to implement
>multidimensional arrays on a lower level?


Actually no because individual elements cannot be accessed directly with
O(1) by pre-calculating the memory location. Instead in Perl the
low-level implementation has to follow the reference chain for each and
every access.

>And if Perl's "array of references" is functionally equivalent to a
>multidimensional array (and it is), then isn't it a multidimensional
>array?


That is debateable. Depending upon which level of abstraction you are
talking about a yes is as justifiable as a no.

jue
 
Reply With Quote
 
Mart van de Wege
Guest
Posts: n/a
 
      10-23-2009
"Uri Guttman" <> writes:

>>>>>> "MvdW" == Mart van de Wege <> writes:

>
> MvdW> (Jens Thoms Toerring) writes:
> >> "multidimensional arrays" (I put that in parantheses since there
> >> aren't real multi- dimensional arrays in Perl but instead you use
> >> arrays of array references to emulate them).

>
> MvdW> (ITYM quotes, not parentheses).
>
> MvdW> What is the difference? Surely this is the most obvious way to implement
> MvdW> multidimensional arrays on a lower level?
>
> MvdW> And if Perl's "array of references" is functionally equivalent to a
> MvdW> multidimensional array (and it is), then isn't it a multidimensional
> MvdW> array?
>
> by the ways classic compiled langs like c does them, then no, perl
> doesn't support multidimensional arrays. in those langs you usually
> predeclare all the array's dimensions and you can directly access
> elements with a fast calculation of the correct offset given the
> indices. in perl's version you have to loop over each dimension then
> index to get the next level down.


Surely this is only true if the dimensions are of unknown size. If your data
model is such that you expect to have fixed size arrays, you can still
directly index into it, even with Perl's model.

I agree it is not common, but functionally multidimensional arrays are
possible to implement with Perl's "array of references" model.

Mart


--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
 
Reply With Quote
 
Mart van de Wege
Guest
Posts: n/a
 
      10-23-2009
Jürgen Exner <> writes:

> Mart van de Wege <> wrote:
>> (Jens Thoms Toerring) writes:
>>
>>> "multidimensional arrays" (I put that in parantheses since there
>>> aren't real multi- dimensional arrays in Perl but instead you use
>>> arrays of array references to emulate them).

>>
>>(ITYM quotes, not parentheses).
>>
>>What is the difference? Surely this is the most obvious way to implement
>>multidimensional arrays on a lower level?

>
> Actually no because individual elements cannot be accessed directly with
> O(1) by pre-calculating the memory location.


Erm.

'Most obvious' != 'Most efficient'.

Certainly pre-calculating is faster, and can't be done in Perl because
the size of the dimensions is unknown, but that's a compiler issue. From
the point of view of the programmer it is quite possible to do
multidimensional arrays, even if the syntax is a bit awkward at times.

>
>>And if Perl's "array of references" is functionally equivalent to a
>>multidimensional array (and it is), then isn't it a multidimensional
>>array?

>
> That is debateable. Depending upon which level of abstraction you are
> talking about a yes is as justifiable as a no.
>

Obviously. And I agree that from the Perl implementer's view it is not
the same.

I am however not a Perl internals hacker. I am a sysadmin who does a bit
of Perl programming to automate tasks and to support business. For me,
if my data model consists of matrix-like structures, an array of
references to arrays looks just like a multidimensional array.

Mart

--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      10-23-2009
>>>>> "MvdW" == Mart van de Wege <> writes:

MvdW> "Uri Guttman" <> writes:
>>>>>>> "MvdW" == Mart van de Wege <> writes:

>>

MvdW> (Jens Thoms Toerring) writes:
>> >> "multidimensional arrays" (I put that in parantheses since there
>> >> aren't real multi- dimensional arrays in Perl but instead you use
>> >> arrays of array references to emulate them).

>>

MvdW> (ITYM quotes, not parentheses).
>>

MvdW> What is the difference? Surely this is the most obvious way to implement
MvdW> multidimensional arrays on a lower level?
>>

MvdW> And if Perl's "array of references" is functionally equivalent to a
MvdW> multidimensional array (and it is), then isn't it a multidimensional
MvdW> array?
>>
>> by the ways classic compiled langs like c does them, then no, perl
>> doesn't support multidimensional arrays. in those langs you usually
>> predeclare all the array's dimensions and you can directly access
>> elements with a fast calculation of the correct offset given the
>> indices. in perl's version you have to loop over each dimension then
>> index to get the next level down.


MvdW> Surely this is only true if the dimensions are of unknown
MvdW> size. If your data model is such that you expect to have fixed
MvdW> size arrays, you can still directly index into it, even with
MvdW> Perl's model.

no you can't. with perl all array accesses require looping over each
dimension. there is no way to directly access a lower level. the code
looks like it does direct access but internally it does a loop over the
indices.

MvdW> I agree it is not common, but functionally multidimensional arrays are
MvdW> possible to implement with Perl's "array of references" model.

that isn't the issue. you can get something which looks and behaves like
a multidim array but it really isn't. this is why i always review code
that repeats deep access code and tell people to factor out the
duplicate code. in fortran and other langs, deep repeated accesses get
the common code optimized out of the loop by common subexpression
removal. perl can't do that due to its dynamic nature so the coder has
to do it. this is where perl's dynamic arrays show that their internal
design is different than fortran and c's.

uri

--
Uri Guttman ------ -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
hash of hash of hash of hash in c++ rp C++ 1 11-10-2011 04:45 PM
Hash#select returns an array but Hash#reject returns a hash... Srijayanth Sridhar Ruby 19 07-02-2008 12:49 PM
XSL variable indirection sucheta.phatak@gmail.com XML 2 09-21-2005 05:44 AM
[xinclude] How to use indirection in xinclude like "Catalog" in the entity world ? SL XML 0 02-15-2005 01:58 PM
Indirection talks to you robin.pain@tesco.net C++ 3 10-09-2003 07:44 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57