0

I do this:

my @items = [];

sub pushItem {
   my $itemId = "i" . sprintf("%d", $_[0]);
   push(@items, $itemId);
}

sub popItems {
   $itemsXml = "<key>items</key>\n<array>\n";

   foreach (@items) {
      $itemsXml .= "<string>$_</string>\n";
   }

   $itemsXml .= "</array>\n";

   return $itemsXml;
}

pushItem(0);
pushItem(1);
pushItem(2);
print popItems();

I get this:

 <key>items</key>
 <array>
 <string>ARRAY(0x7fa1730070d0)</string>
 <string>i0</string>
 <string>i1</string>
 <string>i2</string>
 </array>

The problem of course being:

<string>ARRAY(0x7fa1730070d0)</string>
0

3 Answers 3

5
my @items = [];

should be

my @items = ();
Sign up to request clarification or add additional context in comments.

Comments

3

[] creates an array and a reference to that array, and returns the latter. This means the following populates @items with a reference to a second array in addition to creating @items:

 my @items = [];

You simply want

 my @items;

If you insist on assigning something to it, you'd want to assign a list of zero scalars to it, and you can do that as follows:

 my @items = ();

But really, that's just a waste (since you're clearing an empty array) and it adds needless complexity (code that does nothing).


Just to be clear, @items = (); (as opposed to my @items = ();) is still useful, though only rarely. I think the only time I've used it is in code of the following form:

my @buf;
while (my $item = get()) {
   if (check($item)) {
      something(@buf);
      @buf = ();
   }

   push @buf, $item;
}

something(@buf) if @buf;

4 Comments

I am clearing the array later, so @items = () comes in handy. Thanks! I'm accepting yours for the explanation and because Miguel has lots up of upvotes already. Thanks to both!
Yes, @items = (); is handy (though it's very very very rare to need that). my @items = (); is not handy since it clears an array you've just created (so it's already clear).
Added some clarification to my answer.
Thank you! Now my plist is beautiful. Just in time to deprecate it and go to JSON...
2

Your problem is your first line:

my @items = [];

It should be:

my @items = ();

The problem is that you have assigned an array reference to the first element of the array @items, and then later you push a bunch of other values onto it.

If you initialize it using the parens instead, it does what you want, which is create an empty array. This becomes more apparent if you comment out your calls to pushItem and run the script.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.