Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access list as a hash

I can directly access an element within a list:

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

And I can assign a list to a hash:

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

So, why can't I directly treat a list as a hash?

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

The closest I could find is to create a hashref:

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

Is there a correct syntax to access a list as a hash or why not?

like image 665
stu42j Avatar asked Sep 19 '13 20:09

stu42j


1 Answers

You can't use a list as a hash because lists aren't hashes. :)

The => ("fat comma") operator is the same as ,, with the additional feature that it quotes barewords on the left-hand-side. So when you write this:

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

It's exactly the same as this:

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

And that's not a hash, it's just a list.

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

A hash needs to be constructed before it can be used. Any key/value list assigned to it needs to have the keys hashed and the buckets allocated and the values placed in the buckets. So when you write:

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

What's happening is:

  1. The elements in the list ( 'a', 0, 'b', 1, 'c', 2 ) are put onto the stack
  2. An anonymous hash is constructed by the { LIST } operator
  3. The list elements are popped off the stack and assigned to the hash, turning them into keys and values
  4. A reference to that hash is returned.
  5. The reference is dereferenced by the -> operator
  6. The key c is looked up, and
  7. Its value returned, reducing the expression to $foo = 2

So why can you write (qw(a b c))[2] if a list is not an array? Well, internally the stack is just an array of SV *'s so I imagine that putting the ability to subscript it was simple and seemed like a good idea.

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

like image 73
friedo Avatar answered Oct 16 '22 18:10

friedo