2009-11-13 162 views
1

對於所有這些愚蠢的問題感到抱歉,我一直強調Perl編程,而且我發現很難像Perl程序員那樣思考。今天如何將變量的值用作Perl變量名稱?

愚蠢的問題: 我使用id字段作爲關鍵,像這樣

#open file 

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

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

    $hash{$id} = { 
     "path" => $path, 
     "date" => $date 
    }; 
} 

加載管道分隔文件轉換成散列有幾次,但是,當我真正需要的關鍵是路徑,因爲無論出於何種原因(並且不能改變),id不是唯一的,所以我有一個明智的想法,我可以將它全部放入一個子例程中,並傳遞變量的名稱以使用作爲它的關鍵,有點像這樣:

load_hash("path"); 

sub load_hash { 
    my $key = shift; 

    #do stuff, and then in while loop 
    $hash{${$key}} = #and so on 
} 

但perldb x $ {$ key}始終是undef,儘管x $ {path}將值打印到$ path中。

有沒有某種方式做我想要做的?

TIA

回答

2

是這樣的嗎?

use Carp 'confess'; 

sub load_hash { 
    my $key = shift; 

    # ... 

    while (...) { 
     # ... 
     my %line; # important that this is *inside* the loop 
     @line{qw (id path date)} = split /\|/; 
     confess "BUG: unknown key '$key'" unless exists $line{$key}; # error checking 
     $hash{$line{$key}} = \%line; 
     delete $line{$key}; # assuming you don't want the key value duplicated 
    } 
} 
+0

謝謝,工作。 – Sparkles 2009-11-13 00:57:26

10

您正在嘗試使用「符號引用」。如果您遇到問題,並且您認爲「嗨,我會用符號參考來解決這個問題」,您現在有兩個問題。

首先,他們只適用於全局變量。您已將$path聲明爲詞法(只在聲明的塊中可見),因此load_path無法看到它。不,不要讓$path成爲全球。

其次,符號參考創建意大利麪代碼。全局足夠糟糕。他們可以隨時隨地通過任何方式訪問。通過對全局的符號引用,您甚至無法看到正在訪問哪個全局。這使得跟蹤什麼可能會改變什麼是不可能的。這就是爲什麼strict將其關閉。打開strict並保持打開狀態,直到您知道何時關閉它。

我不完全確定你想要完成什麼,但似乎沒有問題。

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

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

    $hash{$path} = { 
     "path" => $path, 
     "date" => $date 
    }; 
} 

但我可能會將該行的解析移到一個函數中,並將散列分配留給主循環。解析該行是一個明確的邏輯塊,並且可以將該行分配給文件哈希完全分離。一個好兆頭是%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; 
} 
+0

別擔心,我總是使用嚴格和警告(儘管在嘗試此操作時我必須關閉警告)。 – Sparkles 2009-11-13 00:59:06

+3

@Sparkles,如果你不得不關閉警告,你可能做錯了什麼。 – 2009-11-13 04:50:07

+1

upvoted for引用最自以爲是的Perl仇敵活着? (Naggum是最自以爲是的Perl仇敵,但他死了。) – jrockway 2009-11-13 05:33:20