我正在使用子程序来制作一些不同的哈希映射.我目前正在通过引用传递hashmap,但是多次执行时会出现这种情况.我应该按值传递哈希值还是传递哈希引用?
use strict; use warnings; sub fromFile($){ local $/; local our %counts =(); my $string = <$_[0]>; open FILE,$string or die $!; my $contents = <FILE>; close FILE or die $!; my $pa = qr{ ( \pL {2} ) (?{ if(exists $counts{lc($^N)}){ $counts{lc($^N)} = $counts{lc($^N)} + 1; } else{ $counts{lc($^N)} = '1'; } }) (*FAIL) }x; $contents =~ $pa; return %counts; } sub main(){ my %english_map = &fromFile("english.txt"); #my %german_map = &fromFile("german.txt"); } main();
当我单独运行不同的txt文件时,我没有遇到任何问题,但两者都有一些冲突.
解决方法
出于几个原因,您应该使用pass-by-reference,但是您显示的代码会按值返回哈希值.
>除了内置变量(如$/)之外,您应该使用my而不是local,然后才能使用尽可能小的范围.
>子程序的原型几乎不是一个好主意.他们做了非常具体的事情,如果你不知道那是什么,你就不应该使用它们.
>使用&符号来调用子程序,就像在& fromFile(“english.txt”)中一样,自从大约二十年前的Perl 4以来就不正确.它以至少两种不同的方式影响传递给子程序的参数,这是一个坏主意.
>我不确定为什么要使用带有$string =< $_ [0]>的文件glob.您是否期望在作为参数传递的文件名中使用通配符?如果是这样,那么你将打开并只读取第一个匹配的文件,否则不需要glob.
>像$fh这样的词法文件句柄比像FILE这样的裸字文件句柄更好,并且在它们被销毁时会隐式关闭 – 通常在声明它们的块的末尾.
>我不确定您的哈希值计数是如何填充的.没有正则表达式可以填补哈希值,但我必须相信你!
试试这个版本.熟悉Perl的人会感谢你(具有讽刺意味的是!)没有使用驼峰式变量名.并且很少看到声明和调用的主子例程.那是C,这是Perl.
更新我已更改此代码以执行原始正则表达式所做的操作.
use strict; use warnings; sub from_file { my ($filename) = @_; my $contents = do { open my $fh,'<',$filename or die qq{Unable to open "$filename": $!}; local $/; my $contents = <$fh>; }; my %counts; $counts{lc $1}++ while $contents =~ /(?=(\pL{2}))/g; return \%counts; } sub main { my $english_map = from_file('english.txt'); my $german_map = from_file('german.txt'); } main();