我有一个Perl脚本,可将文本文件的每一行加载到哈希中。
&load_map($word_file,"words");
sub load_map {
my ($file_path,$assoc) = @_;
open FILE, $file_path or die "Cannot open file $file_path";
while ($line = <FILE>) {
chomp $line;
$$assoc{$line}=1;
}
close FILE;
}
稍后在脚本中,我查看哈希值以查看是否有一个词,然后再执行以下操作:
if($words{$wordKey}) {
do something...
}
当我在本地环境中运行脚本时,此方法工作正常。当我在docker容器中运行此脚本时,$words{$wordKey}
没有值或找不到,因此我需要运行的代码永远不会执行。
print $words{$wordKey}
在docker容器中为空。在我的本地环境中为1。
奇怪的是,我知道哈希数据确实存在于docker容器中,因为如果我遍历整个哈希并逐个查看键1,我可以看到每个键并最终得到我所使用的键寻找,但这破坏了哈希的全部目的。我不必从头开始遍历整个哈希,直到找到我的密钥为止。
while( my( $key, $value ) = each %words ){
if($key == $wordKey) {
Do something
}
}
有没有人遇到过这个问题,并且了解我可能会做或可能不会做的导致此问题的事情?这让我发疯。
================================================ ================
新代码和输出
情况1:
&preload_words($word_file);
sub preload_words {
my %localhash;
my ($file) = @_;
open my $fh, '<', $file or die "Can't open $file: $!";
my $avalue;
while (my $line = <$fh>) {
chomp $line;
$localhash{$line}=1;
print "word: $line, local value: $localhash{$line} \n";
$avalue = $line;
}
close $fh;
print "a word: $avalue, a value: $localhash{$avalue} \n";
my $bvalue = $localhash{'written'};
print "b word: written, b value: $bvalue \n";
}
outputs:
...
word: worn, local value: 1
word: win, local value: 1
word: won, local value: 1
word: write, local value: 1
word: wrote, local value: 1
word: written, local value: 1 <-- last print from loop
a word: written, a value: 1 <-- avalue last dynamically set from loop
b word: written, b value: 1 <-- hardcoded last word of loop print
情况2:
&preload_words($word_file);
sub preload_words {
my %localhash;
my ($file) = @_;
open my $fh, '<', $file or die "Can't open $file: $!";
my $avalue;
while (my $line = <$fh>) {
chomp $line;
$localhash{$line}=1;
print "word: $line, local value: $localhash{$line} \n";
$avalue = $line;
}
close $fh;
print "a word: $avalue, a value: $localhash{$avalue} \n";
my $bvalue = $localhash{'wrote'};
print "b word: wrote, b value: $bvalue \n";
}
...
word: worn, local value: 1
word: win, local value: 1
word: won, local value: 1
word: write, local value: 1
word: wrote, local value: 1 <-- prints value in loop but nothing outside of loop scope.
word: written, local value: 1 <-- last print from loop
a word: written, a value: 1 <-- avalue last dynamically set from loop
b word: wrote, b value: <-- hardcoded 2nd to last word of loop print returns no value
即使在同一功能内,这似乎也是容器中的某种范围界定问题。一旦退出while循环,我只能直接取消引用最后一个索引。有想法吗?
答案 0 :(得分:6)
我不知道“ docker容器”的作用,但是您使用的是符号引用(从字符串中获取变量名),因此您永远都不要如此轻轻松松...如果有的话;请参见in perlfaq7,this article series和this post(对于初学者)。
此外,这里甚至没有暗示它的原因-而不是使用字符串文字("words"
)来创建哈希名称,而只是传递哈希引用。或在子代码中构建一个哈希值,然后返回它或它的引用
sub load_map {
my ($file) = @_;
open my $fh, '<', $file or die "Can't open $file: $!";
my %assoc;
while (my $line = <$fh>) {
chomp $line;
$assoc{$line} = 1;
}
return \%assoc;
}
并将其作为例如在呼叫方中获取
my %words = %{ load_map('filename') };
如果在此之前调用者中存在哈希的原因,则将其引用传递给子对象
my %words;
...
load_map('filename', \%words);
,然后在子项中使用该哈希值
sub load_map {
my ($file, $assoc) = @_;
...
while (my $line = <$fh>) {
chomp $line;
$assoc->{$line} = 1
}
return 1;
}
请注意,将文件打开到$fh
后,您可以简单地通过以下方式填充哈希值:
my %assoc = map { chomp; $_ => 1 } <$fh>;
由于列表上下文中的readline
(又名<>
)(在此处由map
强制执行,因此会返回文件中的所有行。
但是,上面显式的逐行代码使您可以随时检查等。
我不理解其余的问题(似乎是解释?),但是我在这里解决的问题显然已经消失并正在寻找麻烦(“ docker ”问题可能是由于那?);需要纠正。
答案 1 :(得分:2)
我最终按照zdim的建议使用Data::Dump
打印哈希键,结果表明,从文件构建哈希键时,它以someword\r
的形式存储。
Chomp仅从末尾删除了\n
,而将\r
作为密钥的一部分,这最终导致对密钥的所有取消引用或比较都无法成功。
我将保留大家都建议的代码更改建议,但是想告知任何对此错误的根本原因感兴趣的人。
再次感谢您的所有帮助和建议!