views:

230

answers:

2

Here I am thinking I know how to use lists in Perl, when this happens. If I do this (debugging code, prettiness not included):

#! /usr/bin/perl -w
use strict;

my $temp1 = "FOOBAR";
my $temp2 = "BARFOO!";

my @list = { $temp1, $temp2 };

print $temp1; #this works fine
print $list[0]; #this prints out HASH(0x100a2d018)

It looks like I am printing out the address of the second string. How do I get at the actual string stored inside the list? I assume it has something to do with references, but dunno for sure.

+10  A: 
my @list = { $temp1, $temp2 };

should be

my @list = ( $temp1, $temp2 ); # Parentheses instead of curly braces.

What your original code did was store a reference to a hash {$temp1 => $temp2} into @list's first element ($list[0]). This is a perfectly valid thing to do (which is why you didn't get a syntax error), it's just not what you intended to do.

DVK
My goodness, that was dumber than I thought. The interpreter didn't complain about my poor syntax. What was it doing when I used braces instead of parentheses?
Jergason
@Jergason: {} creates an anonymous hash and returns a reference to it. Your syntax was perfect, just not doing what you wanted.
ysth
That's the price you pay for Perl's expressive power... no rigorous type checking. I like Perl way better but one has to be careful about little details like that as the interpreter is unlikely to deem it unworthy of being valid Perl :)
DVK
+5  A: 

You already got the answer to your question, don't use {}, because that creates an anonymous hash reference.

However, there is still the matter of the question you didn't know you asked.

What is the difference between an array and a list in Perl?

In your question, you use the term 'list' as if it were interchangeable with the term array, but the terms are not interchangeable. It is important to understand the what the difference is.

An array is a type of variable. You can assign values to it. You can take references to it.

A list is an ordered group of zero or more scalars that is created when an expression is evaluated in a list context.

Say what?

Ok, conisder the case of my $foo = (1,2,3). Here $foo is a scalar, and so the expression (1,2,3) is evaluated in a scalar context.

On the surface it is easy to look at (1,2,3) and say that's a literal list. But it is not.

It is a group of literal values strung together using the comma operator. In a scalar context, the comma operator returns the right hand value, so we really have ((1 ,2),3) which becomes ((2),3) and finally 3.

Now my @foo = (1,2,3) is very different. Assignment into an array occurs in a list context, so we evaluate (1,2,3) in list context. Here the comma operator inserts both sides into the list. So we have ((1,2),3) which evaluates to (list_of(1,2),3) and then list_of(list_of(1,2),3), since Perl flattens lists, this becomes list_of(1,2,3). The resulting list is assigned into @foo. Note that there is no list_of operator in Perl, I am trying to differentiate between what is commonly thought of as a literal list and an actual list. Since there is no way to directly express an actual list in Perl, I had to make one up.

So, what does all this mean to someone who is just learning Perl? I'll boil it down to a couple of key points:

  • Learn about and pay attention to context.
  • Remember that your array variables are arrays and not lists.
  • Don't worry too much if this stuff seems confusing.
  • DWIM does, mostly--most of the time the right things will happen without worrying about the details.

While you are pondering issues of context, you might want to look at these links:

daotoad
Great answer, thank you.
Jergason