0

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

    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'}"有价值)

4

3 回答 3

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
    
于 2012-08-27T15:09:43.157 回答
2

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

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

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

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

于 2012-08-27T15:10:42.823 回答
1

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

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

SystemUser{'Password'}

是 Perl 代码,你的配置文件应该只包含数据

但是你可以写,例如

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
于 2012-08-27T15:29:13.183 回答