如何将变量的值用作Perl变量名?

1 variables perl symbolic-references

对于所有这些愚蠢的问题感到抱歉,我已经进入了Perl编程,我发现很难像Perl程序员一样思考.

今天愚蠢的问题:我使用id字段作为键将管道分隔文件加载到哈希中,就像这样

#open file

my %hash;
while (<MY_FILE>) {
    chomp;

    my ($id, $path, $date) = split /\|/;

    $hash{$id} = {
        "path" => $path,
        "date" => $date
    };
}
Run Code Online (Sandbox Code Playgroud)

然而,有几次,当我真正需要键作为路径时,因为无论出于何种原因(并且不能,它无法更改),id不是唯一的,所以我有一个明智的想法,我可以把把它全部放到子程序中并传递变量的名称作为它的关键,有点像:

load_hash("path");

sub load_hash {
    my $key = shift;

    #do stuff, and then in while loop
    $hash{${$key}} = #and so on
}
Run Code Online (Sandbox Code Playgroud)

但是在perldb中,x $ {$ key}始终为undef,尽管x $ {path}会在$ path中打印该值.

有没有办法做我想做的事情?

TIA

Sch*_*ern 10

你正在尝试使用"符号引用".如果你遇到问题而且你认为"嘿,我会用符号引用解决这个问题"你现在有两个问题.

首先,它们只适用于全局变量.您已声明$path为词法(仅在声明的块中可见),因此load_path无法看到它.不,不要做$path全球化.

其次,符号引用创建意大利面条代码.全球足够糟糕.它们可以随时随地访问.通过对全局的符号引用,您甚至无法看到正在访问的WHICH全局.这使得无法追踪可能会改变的内容.这就是strict关闭它们的原因.打开strict并保持打开,直到知道何时应将其关闭.

我不完全确定你想要完成什么,但似乎这很好.

my %hash;
while (<MY_FILE>) {
    chomp;

    my ($id, $path, $date) = split /\|/;

    $hash{$path} = {
        "path" => $path,
        "date" => $date
    };
}
Run Code Online (Sandbox Code Playgroud)

但我可能会将该行解析为一个函数,并将哈希赋值留给主循环.解析该行是一个明显的逻辑块,可以完全分离将行分配给文件哈希.一个好兆头就是%hash不必是全球性的.

my %hash;
while (<MY_FILE>) {
    my $line = parse_line($_);

    my $id = $line->{path};
    $hash{$id} = $line;
}


my @fields = qw(id path date);
sub parse_line {
    my $line = shift;
    chomp $line;

    my %data;
    # This is assigning to a hash slice.  Look it up, its handy.
    @data{@fields} = split m{\|}, $line;

    return \%data;
}
Run Code Online (Sandbox Code Playgroud)

  • @Sparkles,如果你不得不关闭警告,你可能做错了什么. (3认同)