Access list as a hash

I can directly access the element inside the list:

$foo = (qw(abc))[2]; # $foo = "c" 

And I can assign a hash list:

 %h = (a=>0, b=>1, c=>2); $foo = $h{c}; # $foo = 2 

So why can't I directly process the list as a hash?

 $foo = (a=>0, b=>1, c=>2){c}; # Syntax error 

The closest I could find was to create a hashref:

 $foo = {a=>0, b=>1, c=>2}->{c}; 

Is there a correct syntax for accessing a list as a hash or why?

+6
source share
2 answers

You cannot use a list as a hash, because lists are not hashes. :)

The operator => ("bold comma") is the same as,, with an additional attribute in which it quotes left words. Therefore, when you write this:

 ( a=>0, b=>1, c=>2 ) 

This is exactly the same as this:

 ( 'a', 0, 'b', 1, 'c', 2 ) 

And this is not a hash, it's just a list.

Lists are ephemeral things that live on the stack; as you rightly point out, they can be assigned to both arrays and hashes, but they do not match arrays and hashes.

Before it can be used, a hash must be created. Each key / value list assigned to it requires that key hashing and allocated buckets, as well as values, are placed in buckets. Therefore, when you write:

 $foo = {a=>0, b=>1, c=>2}->{c}; 

What's happening:

  • Items in the list ('a', 0, 'b', 1, 'c', 2) are pushed onto the stack
  • An anonymous hash built by the { LIST } operator
  • List items are unloaded from the stack and assigned to the hash, turning them into keys and values
  • A link to this hash is returned.
  • Link is dereferenced by operator ->
  • The c key is scanned and
  • Return value, decreasing expression to $foo = 2

So why can you write (qw(abc))[2] if the list is not an array? Well, internally the stack is just an SV * array, so I suppose the indexing ability was simple and seemed like a good idea.

Here's an article by a really cool guy that you might also find instructive: Arrays vs. Lists in Perl: What's the Difference?

+6
source

No. Because lists are not hashes. The closest you can do is

 my $foo = (a=>0,b=>1,c=>2)[5]; printf("$foo\n"); 

which will print

 2 

as the code above is identical

 my $foo = ('a',0,'b',1,'c',2)[5]; printf("$foo\n"); 
0
source

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


All Articles