我在看别人的代码,他们打开一个文件:
(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
答案 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)
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中打开文件的推荐方法。