从模块返回新的哈希密钥

时间:2015-07-01 16:19:52

标签: perl hash module

我在主脚本中声明了一个哈希,我正在尝试添加一个名为“number”的新密钥并给它一个值。我在一个单独的模块文件中定义的子例程中添加这个新密钥。我遇到的问题是当我在主程序中使用它时,看不到新的键和值。

我期待输出为:

1 
2 
3

但它只是打印回车...好像它没有看到我添加到哈希值的新值。

提前谢谢

以下是我的代码,它演示了我的问题。

主要代码

#!/usr/bin/perl
use test_module;
our %hash;

$hash{a}="";
$hash{b}="";
$hash{c}="";

module::add_number();

my @letters = (sort keys %hash);
for my $letter (@letters) {
    print "$hash{$letter}{number}\n";
}

MODULE CODE

package test_module;

sub add_number {
    $hash{a}{number}=1;
    $hash{b}{number}=2;
    $hash{c}{number}=3;
}

1

2 个答案:

答案 0 :(得分:4)

我不确定你在期待什么。您正在调用不存在的module::add_number - 只有test_module::add_number。并且add_number子例程正在修改$%test_module::hash哈希,而您的主代码正在打印%main::hash

您必须在每个Perl程序的顶部 始终 use strictuse warnings。这将揭示许多容易被忽视的简单错误

你应该避免使用包变量,除非它们是不可避免的。词汇变量 - 用my声明 - 应该是您的首选。此外,诸如包名称之类的全局标识符应该大写,而词汇标识符只使用小写字母

您的主程序将$hash{a}等设置为空字符串,之后add_number子例程要求它们为哈希引用,以便它可以设置子哈希的元素number。如果需要这样做,最好不要初始化哈希元素

最后,如果您需要在单独的子例程中修改它们,而不是声明our变量并使用包名称对其进行完全限定以确定哪个变量,最好通过引用传递散列和数组变量正在谈论

您的代码应如下所示

main.pl

#!/usr/bin/perl

use strict;
use warnings;

use TestModule;

my %hash;

TestModule::add_number(\%hash);

my @letters = sort keys %hash;

for my $letter (@letters) {
    print "$hash{$letter}{number}\n";
}

TestModule.pm

use strict;
use warnings;

package TestModule;

sub add_number {
    my ($hash) = @_;

    $hash->{a}{number} = 1;
    $hash->{b}{number} = 2;
    $hash->{c}{number} = 3;
}

1;

输出

1
2
3

您也可以从add_number导出TestModule,将其更改为此

use strict;
use warnings;

package TestModule;

use Export qw/ import /;
our @EXPORT = qw/ add_number /;

sub add_number {
    my ($hash) = @_;

    $hash->{a}{number} = 1;
    $hash->{b}{number} = 2;
    $hash->{c}{number} = 3;
}

1;

然后主代码中的use TestModule语句将导入add_number标识符,您只需add_number(\%hash)

即可调用它

答案 1 :(得分:4)

%hash部分中的"MAIN CODE"变量和%hash部分中的"MODULE CODE"变量不是相同的变量。其中一个是%main::hash,另一个是%test_module::hash;

如果您希望子程序能够修改变量,则需要将引用传递给该变量:

主要代码:

#!/usr/bin/perl
use test_module;
my %hash;

$hash{a}="";
$hash{b}="";
$hash{c}="";

# | - typo here, needs the 'test_' prefix
# v
test_module::add_number(\%hash); 
# the \ creates a reference to your %hash variable

my @letters = (sort keys %hash);
for my $letter (@letters) {
    print "$hash{$letter}->{number}\n";
}

模块代码:

package test_module;

sub add_number {
    my ($hash_ref) = @_;

    # now that this is a reference, you need to dereference
    # accesses with the -> operator
    $hash_ref->{a} = { number => 1 };
    $hash_ref->{b} = { number => 2 };
    $hash_ref->{c} = { number => 3 };
}

1;