Miq19 has asked for the wisdom of the Perl Monks concerning the following question:

I have a data structure like
my @scales; struct( Scale => { name => '$', offset => '$', foo => '$', index => '$', chords => '@', notes => '@' });
I found no way on how to push data to the @chords and @notes arrays of a record with that structure. I tried f.i.
my $sref = $scales[$scale]->chords; push @{$sref}, $found_chord . ';' . $c[1];
which runs without an issue, but leaves the array empty. If I use Dumper to show the data I get like
... bless( { 'Scale::index' => '8', 'Scale::notes' => [], 'Scale::name' => 'Major Bebop Eb', 'Scale::chords' => [], 'Scale::foo' => 'E61100', 'Scale::offset' => undef }, 'Scale' ), bless( { 'Scale::offset' => undef, 'Scale::foo' => 'E61100', 'Scale::chords' => [], 'Scale::name' => 'Major Bebop F', 'Scale::notes' => [], 'Scale::index' => '9' }, 'Scale' ), ...
which looks like there are just empty arrays in that struct. How is the correct push syntax here?

Replies are listed 'Best First'.
Re: Push to array as part of Struct
by choroba (Cardinal) on Sep 10, 2024 at 14:14 UTC
    I guess you're working with Class::Struct.

    You don't show enough code so I can't tell you directly what to do, but I was able to create an array of the structures and populate an array reference inside:

    #!/usr/bin/perl use warnings; use strict; use Class::Struct; use Data::Dumper; struct(Scale => { name => '$', offset => '$', foo => '$', index => '$', chords => '@', notes => '@' }); my @scales = map 'Scale'->new, 1 .. 5; push @{ $scales[0]->chords }, 'Ami'; print Dumper \@scales;

    Beginning of the output:

    $VAR1 = [ bless( { 'Scale::foo' => undef, 'Scale::chords' => [ 'Ami' ], 'Scale::notes' => [], 'Scale::offset' => undef, 'Scale::name' => undef, 'Scale::index' => undef }, 'Scale' ), bless( { ...

    Update: Fixed the code example.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: Push to array as part of Struct
by LanX (Saint) on Sep 10, 2024 at 14:14 UTC
    This is very confusing code, I have trouble to find a connection between the three snippets you posted.

    Probably try an SSCCE instead?

    Edit

    Please try the ->@* syntax to push to deeply nested elements

    Debugger demo

    DB<4> push $hash{key}[4]{array}->@* , 1..3 DB<5> x \%hash 0 HASH(0xb400007bea0f2180) 'key' => ARRAY(0xb400007bea0f22a0) 0 empty slot 1 empty slot 2 empty slot 3 empty slot 4 HASH(0xb400007bea0f22d0) 'array' => ARRAY(0xb400007bea0f1d08) 0 1 1 2 2 3 DB<6>

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

Re: Push to array as part of Struct
by Fletch (Bishop) on Sep 10, 2024 at 14:57 UTC

    Just a suggestion rather than rolling your own you could use Moose and traits (specifically Moose::Meta::Attribute::Native::Trait::Array) to provide an interface to your fancier, non-scalar members in your instances.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: Push to array as part of Struct
by Miq19 (Novice) on Sep 10, 2024 at 14:21 UTC
    Uh, my bad. The syntax is exactly as I named it - my surrounding logic was wrong (the $scale index was never increased). Sorry bothering you!