在perl中,我如何获取散列的值,其散列名称存储在字符串中?

时间:2012-08-27 14:57:59

标签: perl hash reference

我正在尝试读取散列的值,其名称和索引存储在字符串中。我只能获得值,如果我硬编码哈希及其索引,但不是如果我从另一个变量。为了更好地描述它,我已经提到了以下代码:

    use strict 'vars';
    #------------------------------

    # Hash to store some values
    our %SystemUser = (
                Username => "system",
                Password => "system"
    );

    # Prints successfully if i use the below technique
    print "Using Hard-Coding technique : ${SystemUser{'Password'}}\n";

    my $Reference = "SystemUser{'Password'}";

    # Doesn't print if i use this technique where $Reference contains the hash-index pair 
    print "Using Referencing technique : ${$Reference}\n";

    print "Reference value : $Reference\n";

我想使用SystemUser{'Password'}打印${$Reference}的值(具有$Reference = "SystemUser{'Password'}"值)

3 个答案:

答案 0 :(得分:6)

首先,您应该避免将此作为技术方法。

如果您需要按名称动态获取一组哈希值,那么正确的解决方案(来自Java世界的模式)是将散列存储在hashrefs的散列;使用外部哈希的键是各个哈希名称应该是什么:

my %users = (
     SystemUser => {
            Username => "system",
            Password => "system"
     }
    ,GuestUser => {
            Username => "xxx",
            Password => "xxx"
     }

);
print "$users{SystemUser}->{Password}";

在技术层面,您可以使用解除引用构造${$NAME}

来实现

但是,请记住:

  • 这样做是不好的做法。

    除非你有一个很好的技术理由,为什么你不能像上面那样起诉hashrefs的哈希值,否则不要这样做。

  • 在“use strict”(您应该总是使用)下,根本不允许使用字符串作为参考:

    # WORKS without use strict
    $ perl -e 'our %h=(1=>2); print ${"h"}{1}' 
    
     2
    
    # use strict prohibits that:
    $ perl -e 'use strict; use warnings; our %h=(1=>2); print ${"h"}{1}'
    Can't use string ("h") as a HASH ref while "strict refs" in use 
    
    # but you can unfix by relaxing "strict refs":
    perl -e 'use strict; use warnings; \
        { no strict "refs"; our %h=(1=>2); print ${"h"}{1}; use strict "refs";}'
     2
    

答案 1 :(得分:2)

${}只能返回值本身 - 即哈希,下一对{}中的索引必须保留在外面。

my $Reference = "SystemUser";
my $Field = 'Password';

print "Reference value : ${$Reference}{$Field}\n";

但是,通过命名引用访问全局变量在Perl中是一种不好的做法。你最好使用哈希散列。

答案 2 :(得分:1)

如果通过“0硬编码”你的意思是一切都是参数化的,那么你实际上不能这样做:程序必须至少做出一些假设

但实际上大多数数据都是可配置的,尽管这样做的方法不是将Perl代码存储在配置文件中

SystemUser{'Password'}

是Perl代码,您的配置文件应该只包含 data

但你可以写,例如

use strict;
use warnings;

my %config = (
    SystemUser => {
        Username => 'system',
        Password => 'system'
    }
);

while (<DATA>) {
    my ($domain, $field) = split;
    print "Value: $config{$domain}{$field}\n";
}
__DATA__
SystemUser Password

<强>输出

Value: system