Perl哈希:我不明白为什么以及发生了什么

时间:2016-05-26 13:11:56

标签: perl

我有以下代码:

$data->{reports}->{ $args->{port} }->{tb}->{tb}->{'2|LIABILITIES|24974-000'} = 0
        if ( !defined( $data->{reports}->{ $args->{port} }->{tb}->{tb}->{'2|LIABILITIES|24974-000'} ) ); # advisory    

$data->{reports}->{ $args->{port} }->{tb}->{tb}->{'2|LIABILITIES|24975-000'} = 0
        if ( !defined( $data->{reports}->{ $args->{port} }->{tb}->{tb}->{'2|LIABILITIES|24975-000'} ) ); # operating         

$data->{reports}->{ $args->{port} }->{tb}->{tb}->{'1|ASSETS|11150-800'} = 0
        if ( !defined($data->{reports}->{ $args->{port} }->{tb}->{tb}->{'1|ASSETS|11150-800'} ) );       # change in market    

$data->{reports}->{ $args->{port} }->{tb}->{tb}->{'1|ASSETS|11150-000'} = 0
        if ( !defined($data->{reports}->{ $args->{port} }->{tb}->{tb}->{'1|ASSETS|11150-000'} ) );       # book value    

$data->{reports}->{ $args->{port} }->{tb}->{change}->{'3|INCOME|46515-000'} = 0
        if ( !defined($data->{reports}->{ $args->{port} }->{tb}->{change}->{'3|INCOME|46515-000'} ) );   # dividend_income  

我不明白这段代码的作用。也许它将哈希$data密钥reports与哈希$arg密钥port,哈希tb等连接起来

2 个答案:

答案 0 :(得分:5)

它所做的只是将一些嵌套哈希值设置为零(如果它们当前为undef)。它可以写得更干净

此代码是等效的。它进行了这些更改

  • 将根哈希引用解压缩到变量$tb

  • 删除不必要的间接操作符->

  • 使用已定义或赋值运算符 //=

    a //= b表示a = b unless defined a

我希望这对你来说更清楚

my $tb = $data->{reports}{ $args->{port} }{tb};

$tb->{tb}{'2|LIABILITIES|24974-000'} //= 0; # advisory    
$tb->{tb}{'2|LIABILITIES|24975-000'} //= 0; # operating         
$tb->{tb}{'1|ASSETS|11150-800'}      //= 0; # change in market    
$tb->{tb}{'1|ASSETS|11150-000'}      //= 0; # book value 
$tb->{change}{'3|INCOME|46515-000'}  //= 0; # dividend_income  

答案 1 :(得分:4)

我重新缩进了代码并将if !defined替换为unless。我还删除了括号,以便更容易理解正在发生的事情。

# advisory
$data->{reports}->{ $args->{port} }->{tb}->{tb}->{'2|LIABILITIES|24974-000'} = 0
    unless defined $data->{reports}->{ $args->{port} }->{tb}->{tb}->{'2|LIABILITIES|24974-000'};

# operating         
$data->{reports}->{ $args->{port} }->{tb}->{tb}->{'2|LIABILITIES|24975-000'} = 0
    unless defined $data->{reports}->{ $args->{port} }->{tb}->{tb}->{'2|LIABILITIES|24975-000'};

# change in market    
$data->{reports}->{ $args->{port} }->{tb}->{tb}->{'1|ASSETS|11150-800'} = 0
    unless defined $data->{reports}->{ $args->{port} }->{tb}->{tb}->{'1|ASSETS|11150-800'};

# book value 
$data->{reports}->{ $args->{port} }->{tb}->{tb}->{'1|ASSETS|11150-000'} = 0
    unless defined $data->{reports}->{ $args->{port} }->{tb}->{tb}->{'1|ASSETS|11150-000'};

# dividend_income  
$data->{reports}->{ $args->{port} }->{tb}->{change}->{'3|INCOME|46515-000'} = 0
    unless defined $data->{reports}->{ $args->{port} }->{tb}->{change}->{'3|INCOME|46515-000'}; 

它现在读得好多了,因为它几乎是英语。

Perl中有一个 postfix if命令,意味着运行此行如果以下是真的。我替换的unless是相同的,只是,如果不是

这实际上只是一个操作重复五次,具有不同的值。如果定义了某个值,它会在$data数据结构中查找,这意味着它不是undef。如果不是这种情况,则会在此处设置默认值0

整个代码可以更容易阅读:

my $tb = $data->{reports}->{ $args->{port} }->{tb};
$tb->{tb}->{'2|LIABILITIES|24974-000'} //= 0;    # advisory
$tb->{tb}->{'2|LIABILITIES|24975-000'} //= 0;    # operating
$tb->{tb}->{'1|ASSETS|11150-800'}      //= 0;    # change in market
$tb->{tb}->{'1|ASSETS|11150-000'}      //= 0;    # book value
$tb->{change}->{'3|INCOME|46515-000'}  //= 0;    # dividend_income

这意味着同样的事情。我首先采用了内部数据结构的一部分并将其分配给变量。因为这些都是引用,所以不是副本,而是指针。 The //= operator表示如果未定义该值,则将右侧值分配给左侧值。那是added in Perl 5.9.0。现在你的代码更具可读性。