变量不受保护

问题描述

我有这个来源 第一次启动.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);

和包裹

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;

输出是这样的

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

不知何故,我想将树顶和遍历元素之间的 VAL 数组收集到一个数组中。方式是在第二级的最后一个 VAL 有 7 个元素。我只想拥有 2 个元素(alfa 和 beta)

这是预期的输出

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)

...

解决方法

如果只想累加当前分支中的值,则必须传递进位数组的副本。 [@$carry] 取消引用 arrayref $carry 并从元素创建一个新的 arrayref。我在函数的末尾保留了调试打印的原始参考。更自然的方式是写 $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 ","\n";
        push(@{$new_carry},@{$self->{VAL}})
    }
    print $tab," carry=",$#{$new_carry}+1,@$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 ","]\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);

打印:

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,beta]
    |   |   | carry=3 [BEGIN,beta]
    |   |   | Running initialize pentru stud1
    |   |   |   | _initialized called with carry  [BEGIN,beta]
    |   |   |   | Have found val=delta gama
    |   |   |   | pushing delta gama
    |   |   |   | carry=5 [BEGIN,beta,delta,gama]
    |   |   |   | returning to previous level. carry was  [BEGIN,beta]
    |   |   | Running initialize pentru stud2
    |   |   |   | _initialized called with carry  [BEGIN,beta]
    |   |   |   | Have found val=omega upsilon
    |   |   |   | pushing omega upsilon
    |   |   |   | carry=5 [BEGIN,omega,upsilon]
    |   |   |   | returning to previous level. carry was  [BEGIN,beta]
    |   |   | returning to previous level. carry was  [BEGIN,beta]
    |   | returning to previous level. carry was  [BEGIN]
    | returning to previous level. carry was  [BEGIN]

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...