如何在Perl中跟踪全局变量?

时间:2011-11-05 00:16:10

标签: perl file io

我在看别人的代码,他们打开一个文件:

(open (FILEHANDLE,'/homedirectory/textfile.txt')) 
然后,他们将每行的内容放入一个变量进行处理(文件的每一行都包含由制表符分隔的数据):

while(<FILEHANDLE>) {
($var1, $var2, $var3, $var4) = split (/\t+/, $_);
然后他做了类似的事情:

$index = join('_', $var1, $var2, $var3);

然后做到这一点(我划伤脑袋的部分)

$contents = $filehandle{"$index"};

我尝试打印$contents,看起来$var1$var2$var3的值都用分号分隔(例如“{{1 }}“)。另外,我将value1;value2;value3的名称更改为FILEHANDLE并对FILEHANDLE2执行了同样的操作,我得到了完全相同的结果,因此这让我相信它们是相关的。此外,单独离开$filehandle并将FILEHANDLE更改为$filehandle时,不会显示任何内容。任何帮助将不胜感激,因为我已经坚持了很长一段时间。另外,我是一个perl n00b ...(我主要使用Python编程)。

根据要求,这是一个更完整的代码版本:

$filehandle2

要清楚,sub myfn{ $filename = "home/textfile.txt"; open(FILEHANDLE, $filename) || die "Can't find filename\n"; while (<FILEHANDLE>) { ($var1, $var2, $var3) = split (/\t+/, $_); $used_index = join ('_', $var1, $var2, $var3); $tmp_index = uc ($used_index) $contents = $filehandle{"$tmp_index"}; 在这个时刻第一次出现......也可能会注意到之前设置了类似名称的东西,但它是这样的:

$filehandle

2 个答案:

答案 0 :(得分:7)

简短回答:正如卡罗宁先生所提到的那样,标识符filehandle(在您的情况下,考虑使用$filehandle{$key},标识符是哈希%filehandle)没有任何关系赤字FILEHANDLE。它们碰巧被命名为相似(但完全不同,因为Perl区分大小写)。

最有可能的是,散列%filehandle - 由于其值似乎实际上不是文件句柄而被命名为非常糟糕 - 在代码中的其他位置填充。要验证这一点,您需要做两件事:

  • 在您的文件上运行grep命令,如下所示:grep filehandle your_file.pl

  • 通过以下方式启动方法,检查调用子例程时该哈希的内容是什么:

    sub myfn{
        use Data::Dumper; 
        print Data::Dumper->Dump([\%filehandle]);
    
  • 通过Perl调试器运行脚本,查看代码中变量的位置(使用当前命令行并将其与perl -d预先挂起)。在调试器中时,通过发出命令w %filehandle设置监视表达式,然后通过c执行脚本(继续)

查看发布的代码,似乎使用全局变量以非常差的形式编写。你理解它的问题是100%完美的例子,说明为什么在任何语言中使用全局变量都是一个非常糟糕的想法。将此与我为此目的编写的代码进行对比(假设我猜测%filehandle是正确的):

# Caller code
my %file_data = (1=>2); # What the original code called %filehandle hash
myfn(\%file_data); # Pass by reference

sub myfn {
    my($file_data) = @_; # A hashref, passed from caller code
    my $filename = "home/textfile.txt";
    open(my $filehandle, "<", $filename) || die "Can't find filename. Error: $!\n";
    while (<$filehandle>) {
        my ($var1, $var2, $var3) = split (/\t+/, $_);
        my $used_index = join ('_', $var1, $var2, $var3);  
        my $uc_index = uc($used_index);
        my $contents = $file_data->{$uc_index}; # Using -> to dereference hashref

答案 1 :(得分:0)

perldoc perlopentut。两个

open FILEHANDLE, '<', 'filename' or die $!;
while (<FILEHANDLE>) {
    # do something with $_
}
close FILEHANDLE;

open $filehandle, '<', 'filename' or die $!;
while (<$filehandle>) {
    # do something with $_
}
close $filehandle;

是打开和读取文件的有效方法,但是明文FILEHANDLE和标量变量$filehandle彼此无关(除非您之前已设置$filehandle = \*FILEHANDLE或类似的东西)。你甚至可以做

open my $filehandle, '<', 'filename' or die $!;
while (<$filehandle>) {
    # do something with $_
}
# file is closed automatically when $filehandle goes out of scope
实际上,有些人会认为这是在现代Perl中打开文件的推荐方法。