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

Dear Masters,

I am trying to accumulate a deep array reference into another array after passing them into certain conditional test.

The problem I have is that while printing line by line the deep reference it prints nicely. It's only after I accumulate these array references, Dumper prints gave a strange result. Why is that? I think my construct is already correct. Here is the portion of the code that gave problem I encounter:
#.... my @accum; foreach my $int (@intervals ) { if (num_of_tupl($int) >= 4) { print Dumper $int; # It prints correctly in this line push @accum,$int; } } print "ACCUM: "; print Dumper \@accum ; # Problem here
And the sample problematic answer is this:
$VAR1 = [ [['A','3','C']], [['C','-4','B'],['B','-4','A'],['A','3','C'],['C','-4','B']] ]; $VAR1 = [ [['A','3','C'],['C','-4','B'],['B','-4','A'],['A','3','C']], [['C','-4','B']] ]; # Problem begins here ACCUM BOTH ABOVE: $VAR1 = [[ [['A','3','C']], [['C','-4','B'],['B','-4','A'],['A','3','C'],['C','-4','B']]], [[$VAR1->[0][0][0], $VAR1->[0][1][0], $VAR1->[0][1][1], $VAR1->[0][1][2]], [$VAR1->[0][1][3]]] ];
Below is my full code:
#!/usr/bin/perl -lw use strict; use Algorithm::Loops 'NestedLoops'; use Data::Dumper; $Data::Dumper::Indent = 0; my $set = { 'key1' => ['A -4 A','A -1 C','C -4 D','D -4 B','B -3 C','C -4 B','B -1 E'], 'key2' => ['A -1 B','B -1 C','C -4 A','A -5 B'], 'key3' => ['A 3 C','C -4 B','B -4 A','A 3 C','C -4 B'], }; my $delim = 'A 3 C -4 B'; get_region_wth_idx($delim,$set); sub get_region_wth_idx { my ($delim,$set) = @_; my %hash; OUT: foreach my $setkey ( sort keys %{$set} ) { print "\n"; print "$setkey\n"; my @delim = decomp_str2aoa($delim); my @data = decomp_a2aoa($set->{$setkey}); my $N = $#data; my $D = $#delim; my @intervals = NestedLoops( [ [0 .. $N], sub {[$_ .. $N]}, ( sub {[$_+1 .. $N]}, sub {[$_ .. $N]} ) x $D ], { OnlyWhen => sub { return 0 if @_ < 2*@delim; for my $d (0 .. $D) { if ($data[ $_[ $d*2 ] ][0] ne $delim[$d][0] or $data[ $_[ $d*2 + 1 ] ][2] ne $delim[$d][2]) { return 0; } } return 1; } }, sub { return [ map { [@data[ $_[2*$_] .. $_[2*$_+1] ]] } 0 .. $D ]; } ); my @accum; foreach my $int (@intervals ) { if (num_of_tupl($int) >= 4) { print Dumper $int; push @accum,$int; } } print "ACCUM BOTH ABOVE: "; print Dumper \@accum ; } # $hash{$setkey} = [ @accum ]; # print Dumper \%hash ; print "\n"; return ; } #--------- Additional subroutine ------- sub num_of_tupl { # Just a simple code, counting # how many tuples (e.g.["A", -3, "C"] ) contain in AoA my $ar = shift; my $count; foreach my $lvl1 ( @{$ar} ) { my $sizein = scalar(@{$lvl1}); $count += $sizein; } return $count; } sub decomp_str2aoa { return decomp_a2aoa([$_[0] =~ /(?=([a-z]\s*(?:\S+\s*){2}))\S+\s*/gi]); } sub decomp_a2aoa { my $arr = shift; return map{ [split(" ",$_)] }@{$arr}; }


---
neversaint and everlastingly indebted.......

Replies are listed 'Best First'.
Re: Problem in Accumulating Deep Array References
by fishbot_v2 (Chaplain) on Oct 17, 2005 at 11:55 UTC

    Set $Data::Dumper::Deepcopy to 1, and see if the output is what you expected. If so, then the problem is with the way Dumper formats output not being what you expect. More likely, the web of references you are creating are more complex than you think.

    When Dumper sees a reference to something it has already printed, then it represents that data as an internal reference... in the source data they are bound together, so Dumper prints them bound together.

    If you don't want them bound (ie. multiple references to the same data) then you will have to copy the data, rather than the references. If you just don't want them printed bound, then the Dumper setting is sufficient.

Re: Problem in Accumulating Deep Array References
by Anonymous Monk on Oct 17, 2005 at 11:20 UTC
    I've never posted to perl monks before. Nor have I ever used Algorithm::Loops, so I'm not exactly sure what is going on. But the Data::Dumper seems to be printing out perfectly correct and expected results. If you take the $VAR1->[0][0][0], etc. to be internal references back into the structure, you can see that it is doing a reference back into itself. And it makes sense: all your tuples in the second $int are the same, except re-grouped, which is exactly what is happening. So as far as I can see things look fine, except, perhaps, you expected new copies of tuples where there aren't any. Mark