Rolf Haugaland
Rolf Haugaland

Reputation: 25

Perl push an element into an array that is inside of another array

I have an array(lets call it X) and X contains arrays. I want to push an element(a string) into an array that is inside of X. I've tried searching for quite a while and all i find are people trying to push arrays inside of other arrays.

I've tried the following code:

push(@X[0],$element);

Which gives me the error:

Experimental push on scalar is now forbidden at perlscript.pl line 30, near "$element)"

I'm on perl 5 version 26.

Upvotes: 2

Views: 1931

Answers (4)

SpiceMan
SpiceMan

Reputation: 74

Like everybody mentioned already, push @{ $X[0] }, $element;.

Since you say you are using v5.26, you can also use postfix dereferencing:

push $X[0]->@*, $element;

Upvotes: 1

ikegami
ikegami

Reputation: 385506

The syntax for push is

push ARRAY, LIST

For example,

push @a, $element;

Whereever a variable name appear, you may replace the name with a block that evaluate to an reference.

push @{ $X[0] }, $element;

And that's what you need.

Upvotes: 3

simbabque
simbabque

Reputation: 54323

In Perl, arrays cannot contain other arrays. To make a multi-dimensional data structure, you need references.

Consider this example.

use strict; use warnings;
use Data::Dumper;

my @inner = qw(a b c);
my @outer = (
    \@inner,         # reference to existing array
    [100, 200, 300], # new anonymous array reference
);

print Dumper \@outer;

This prints

$VAR1 = [
          [
            'a',
            'b',
            'c'
          ],
          [
            100,
            200,
            300
          ]
        ];

Your outer array is just that, an array. But the elements inside it are references to arrays. You can either reference an existing array, or create a new, anonymous one.

When dumping out the structure for debugging, note how Dumper from Data::Dumper requires a reference too, so we use the same notation with the \.

Now to add an element to @inner via its position inside @outer, you need to take the first element out @outer. To do that, the sigil changes, so you get $outer[0]. To pass that to push, we need to turn it into an array. That's called dereferencing as an array.

push @{ $outer[0] }, 'd';

When we Dumper it again, we get

$VAR1 = [
          [
            'a',
            'b',
            'c',
            'd'
          ],
          [
            100,
            200,
            300
          ]
        ];

Because the first element is a reference to a named array variable, we can also operate on it directly.

push @inner, 'e';

This will change the value of the first element in @outer, because both refer (see why it's called a reference?) to the same thing in memory.

$VAR1 = [
          [
            'a',
            'b',
            'c',
            'd',
            'e'
          ],
          [
            100,
            200,
            300
          ]
        ];

We can't do that with the second element, because it started out as an anonymous reference.


Let's have a look at your warning.

Experimental push on scalar is now forbidden at perlscript.pl line 30, near "$element)"

In Perl 5.20.0 push on references was deprecated because it didn't work as intended, and started warning. In Perl 5.30.0 this was changed and it is now a fatal error, making your program die.

Also see perlref and perlreftut.

Upvotes: 6

GMB
GMB

Reputation: 222382

I think that this does what you want:

push @{ $X[0] }, $element;

Upvotes: 2

Related Questions