{...">

Perl referencing hash dereferencing

Consider the following simple code snippet:

%hash = ('a'=>1,'b'=>2); print $hash{'b'}; print "\n",(\%hash)->{'b'}; #used when hashes are passed by reference #to subroutines 

The conclusion, as expected, is a pair of two. But I thought that $ hash {key} is a shorthand for links and dereferences executed as (\% hash) → {key}, or it is a completely different way to achieve the same result.

Please provide some clarification.

+4
source share
3 answers

They are slightly different, because unlike many other languages, where all complex types are available only as links, Perl has an actual simple hash type and a separate reference type, which can act as a proxy server for any other type. This can be found in perlguts .

In the end, these two examples retrieve data from one storage, of course, but the second call is a bit longer because it spends time obediently, creating a link to a regular HV, and then looking for it back the way you asked. You can learn the details of what is happening under the hood using B::Concise .

 %hash = ('a'=>1,'b'=>2); print $hash{'b'}; print (\%hash)->{'b'}; 

Brief conclusion:

 $ perl -MO=Concise deref.pl t <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 deref.pl:1) v:{ ->3 b <2> aassign[t3] vKS ->c - <1> ex-list lKP ->8 3 <0> pushmark s ->4 4 <$> const[PV "a"] s ->5 5 <$> const[IV 1] s ->6 6 <$> const[PV "b"] s ->7 7 <$> const[IV 2] s ->8 - <1> ex-list lK ->b 8 <0> pushmark s ->9 a <1> rv2hv[t2] lKRM*/1 ->b 9 <#> gv[*hash] s ->a c <;> nextstate(main 1 deref.pl:2) v:{ ->d i <@> print vK ->j d <0> pushmark s ->e h <2> helem sK/2 ->i f <1> rv2hv sKR/1 ->g e <#> gv[*hash] s ->f g <$> const[PV "b"] s ->h j <;> nextstate(main 1 deref.pl:3) v:{ ->k s <2> helem vK/2 ->t q <1> rv2hv[t7] sKR/1 ->r p <@> print sK ->q k <0> pushmark s ->l o <1> refgen lK/1 ->p - <1> ex-list lKRM ->o l <0> pushmark sRM ->m n <1> rv2hv[t6] lKRM/1 ->o m <#> gv[*hash] s ->n r <$> const[PV "b"] s ->s deref.pl syntax OK 
+1
source

But I thought that $ hash {key} is a shorthand for links and dereferences performed as (\% hash) → {key}, or it is a completely different route to achieve the same result.

No, $ hash {key} is just access to% hash in the same way that $ array [0] is just access to @array. But the \% hash is a reference to% hash and therefore requires dereferencing to access it. The syntax (\%hash)->{key} would be short for:

 do { my $temp_ref = \%hash; $temp_ref->{key} } 

But if you have hash hash, $ hash {key} works beautifully without useless reference / dereferencing. Hashes and arrays (as a rule) are passed by reference to subprograms, since smoothing the list of pearls makes it difficult to transfer more than one. (One common exception is a function that implements named parameters.)

See perldoc perreftut and perldoc perlref for a full explanation of references in perl.

+1
source

The sigle ($% @) changes in Perl 5 because it reflects the available value.

 my @a = (10, 20, 30); # Whole array print $a[1]; # Single scalar element of @a my %h = (a=>1, b=>2); # Whole hash print $h{a}; # Single scalar value from %h 

All links refer to "$" since they are all scalars. Does it help?

0
source

Source: https://habr.com/ru/post/1413921/


All Articles