【问题标题】:In Perl, why am I getting "reference found where even-size list expected" when I try to initialize a hash? [duplicate]在 Perl 中,当我尝试初始化哈希时,为什么会出现“在预期的偶数列表中找到参考”? [复制]
【发布时间】:2023-04-03 14:48:01
【问题描述】:

我有一个将两个文件作为输入的脚本:

  • 20 万行的提取
  • 源文件

我必须将提取与源进行比较:提取的每一行都应该在源中。如果没有,我必须在日志文件中记录该行。

在脚本下方:

#!/perl/bin/perl
use strict;
use warnings;
use feature 'say';
# Open log file
open(LOG, '>', 'log.txt');
# Start log
say LOG '['.localtime().'] Début execution';
# Declare extraction number of line counter
my $i_extraction_counter = 1;
# Define files to be compared (extraction against source)
my ($extraction_file, $source_file) = @ARGV;
# Open extraction file
open my $f_extraction, "<", $extraction_file;
# Store extraction file in a hash
my %h_extraction;
while(defined(my $extr_line = <$f_extraction>)){
    $h_extraction{$extr_line} = $extr_line;
    $i_extraction_counter++;
}
# Declare temp hash and counter
my %h_tmp = {};
my $i_counter = 1;
# Open source file
open my $f_source, "<", $source_file;
# For each source line, compare against extraction hash
while(defined(my $source_line = <$f_source>)){
    # If the current line exists in extration hash, stores it in the temp hash & increase counter
    if(defined($h_extraction{$source_line})){
        $h_tmp{$source_line} = $source_line;
        $i_counter++;
    }
    # TO DO : check in elsif if the line should be stored in log (name + firstname OR contract number)
}
# If not all lines of extraction has been stored in temp hash = some lines of extraction are not in source file
if($i_counter < $i_extraction_counter){
    # Declare a second temp hash (used to log missing lines)
    my %h_missing_lines = %h_extraction;
    # For each line of extraction, check if it exists in the first temp hash. If yes, unset it. Only missing line will remain
    foreach my $s_line (keys(%h_missing_lines)){
        if(defined($h_tmp{$s_line})){
            delete($h_missing_lines{$s_line});
        }
    }
    # For each line of missing lines hash, stores it in log file
    foreach my $s_line (keys(%h_missing_lines)){
        say LOG 'Ligne d\'extraction non présente dans fichier source : '.$s_line;
    }
}
say LOG '['.localtime().'] Fin execution';

在执行时,显示此消息:Reference found where even-sized list expected at script.pl line 22, &lt;$f_extraction&gt; line 200000.

【问题讨论】:

  • 这是一个很好的例子,use diagnostics 很好地解释了问题。试试perl -Mdiagnostics -E'my %h = {}'
  • @DaveCross:我同意,但程序中的use diagnostics 会吐出大量无用的词。像使用perl -d 一样用作perl -Mdiagnostics 是必不可少的。把它放在代码之外。
  • PERL5OPT 的好用处 :-)

标签: perl hash


【解决方案1】:

在第 22 行,我们有:

my %h_tmp = {};

将其更改为:

my %h_tmp;

你会没事的。

这里的问题是 - {} 用于定义匿名哈希 - 并返回一个引用。

所以你可以这样做:

my $hash_ref = {}; 

这就是你正在做的事情。

my %h_tmp = $hash_ref; 

像这样使用单个值初始化散列会给出您得到的错误,因为散列需要键值对。

你可以这样做:

my %h_tmp = (); 

这可行,但会是多余的 - 无论哪种方式,您都在创建一个空哈希。

【讨论】:

  • 就是这样!!谢谢:)
  • @PierrickFlajoulot:除此之外,虽然您的代码可能工作,但您似乎害怕空白、缩进、布局等。
  • "perltidy" 又大又聪明 :)
  • @Borodin:我用 PHP 编写代码的方式。但你是对的,有一些空格会更清楚
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-08
  • 2016-10-24
  • 2017-08-20
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
相关资源
最近更新 更多