The variable is not protected

Viewed 74

i have this sources first start.pl

use strict;
use warnings;

use hh;

print "Starting...\n";

my $abc={
    VAL=>['alfa','beta'],
    STUDENTS=>{
        stud1=>{VAL=>['delta','gama']},
        stud2=>{VAL=>['omega','upsilon']},
            }
    };
my $object=hh->new(catalog=>$abc);

and the package

package hh;
use strict;
use warnings;

sub new {
    my $class=shift;
    my $self={@_};
    bless ($self,$class) ; 
    $self->_initialize("",['BEGIN']);
    return $self ; 
}




sub _initialize {
    my $self=shift;
    my $tab=shift;
    my $carry=shift;
    $tab=$tab."\t|";
    
    if (defined $self->{VAL}){print "$tab Have  val=",join(" ",@{$self->{VAL}}),"\n";push(@{$carry},@{$self->{VAL}})}
    foreach my $k (sort {lc $a cmp lc $b} keys %{$self}){
        print $tab,"carry=",$#{$carry}+1," "," ",$k,"\n";
        if (ref($self->{$k}) eq 'HASH'){print "$tab Running initialize pentru $k\n";_initialize($self->{$k},$tab,$carry)}
    }

return $self;
}

1;

the output is like this

Starting...
    |carry=1  catalog
    | Running initialize pentru catalog
    |   | Have  val=alfa beta
    |   |carry=3  STUDENTS
    |   | Running initialize pentru STUDENTS
    |   |   |carry=3  stud1
    |   |   | Running initialize pentru stud1
    |   |   |   | Have  val=delta gama
    |   |   |   |carry=5  VAL
    |   |   |carry=5  stud2
    |   |   | Running initialize pentru stud2
    |   |   |   | Have  val=omega upsilon
    |   |   |   |carry=7  VAL
    |   |carry=7  VAL

Somehow i want to collect into an array the VAL arrays between top of tree and the walked element . Way the last VAL who is in the second level has 7 elements . I want to have only 2 elements (alfa and beta)

this is the expected output

Starting...
    |carry=1  catalog
    | Running initialize pentru catalog
    |   | Have  val=alfa beta
    |   |carry=3  STUDENTS
    |   | Running initialize pentru STUDENTS
    |   |   |carry=3  stud1
    |   |   | Running initialize pentru stud1
    |   |   |   | Have  val=delta gama
    |   |   |   |carry=5  VAL   carry=5                  (OK)
    |   |   |carry=5  stud2
    |   |   | Running initialize pentru stud2
    |   |   |   | Have  val=omega upsilon
    |   |   |   |carry=7  VAL      carry=5   (not ok this need only his values catalog alfa beta omega epsilon)
    |   |carry=7  VAL not ok (carry 3  only catalog alfa beta)

...

1 Answers

If you want to accumulate only the values in the current branch, you have to pass a copy of the carry array. [@$carry] dereferences the arrayref $carry and creates a new arrayref from the elements. I kept the original reference for the debug print at the end of the function. The more natural way would be to write $carry = [@$carry].

use strict;
use warnings;

package hh;
use Data::Dumper;
sub new {
    my $class=shift;
    my $self={@_};
    bless ($self,$class) ; 
    $self->_initialize("",['BEGIN']);
    return $self ; 
}




sub _initialize {
    my $self=shift;
    my $tab=shift;
    my $carry=shift;
    $tab=$tab."\t|";
    print "$tab _initialize() called with carry "," [",join(', ',@$carry),"]\n";
    my $new_carry =  [@$carry];
    if (defined $self->{VAL}){
        print "$tab Have found val=",join(" ",@{$self->{VAL}}),"\n";
        print "$tab pushing ",join(" ",@{$self->{VAL}}),"\n";
        push(@{$new_carry},@{$self->{VAL}})
    }
    print $tab," carry=",$#{$new_carry}+1," [",join(', ',@$new_carry),"]\n";

    foreach my $k (sort {lc $a cmp lc $b} keys %{$self}){
        if (ref($self->{$k}) eq 'HASH'){print "$tab Running initialize pentru $k\n";_initialize($self->{$k},$tab, $new_carry)}
    }
    print "$tab returning to previous level. carry was "," [",join(', ',@$carry),"]\n";
    return $self;
}

package main;
print "Starting...\n";

my $abc={
    VAL=>['alfa','beta'],
    STUDENTS=>{
        stud1=>{VAL=>['delta','gama']},
        stud2=>{VAL=>['omega','upsilon']},
            }
    };
my $object=hh->new(catalog=>$abc);

This prints:

Starting...
    | _initialized called with carry  [BEGIN]
    | carry=1 [BEGIN]
    | Running initialize pentru catalog
    |   | _initialized called with carry  [BEGIN]
    |   | Have found val=alfa beta
    |   | pushing alfa beta
    |   | carry=3 [BEGIN, alfa, beta]
    |   | Running initialize pentru STUDENTS
    |   |   | _initialized called with carry  [BEGIN, alfa, beta]
    |   |   | carry=3 [BEGIN, alfa, beta]
    |   |   | Running initialize pentru stud1
    |   |   |   | _initialized called with carry  [BEGIN, alfa, beta]
    |   |   |   | Have found val=delta gama
    |   |   |   | pushing delta gama
    |   |   |   | carry=5 [BEGIN, alfa, beta, delta, gama]
    |   |   |   | returning to previous level. carry was  [BEGIN, alfa, beta]
    |   |   | Running initialize pentru stud2
    |   |   |   | _initialized called with carry  [BEGIN, alfa, beta]
    |   |   |   | Have found val=omega upsilon
    |   |   |   | pushing omega upsilon
    |   |   |   | carry=5 [BEGIN, alfa, beta, omega, upsilon]
    |   |   |   | returning to previous level. carry was  [BEGIN, alfa, beta]
    |   |   | returning to previous level. carry was  [BEGIN, alfa, beta]
    |   | returning to previous level. carry was  [BEGIN]
    | returning to previous level. carry was  [BEGIN]
Related