通过引用加上标量变量传递一个Perl哈希值

时间:2019-06-04 13:13:46

标签: perl hash reference

我试图通过引用和标量值将Main.pl传递给子目录(在ReadConfigFile.pm中)。标量变量是配置文件的路径,一旦打开该文件,我想用其某些值填充哈希值。我该如何通过引用和标量传递哈希,以便可以在Main.pl中使用哈希值

我已经读了很多书,但是无法正常工作。我意识到我做不到= @_;在我的子目录中,因为这将创建一个新的哈希。

我尝试按照原型方法进行操作,这可以很好地填充哈希值,但在Main.pl中,哈希值为空。

Main.pl

# Read the config file.  Return 3 scalars and a hash
my %apps;
my ($schema, $directory, $staticFile) = readConfigFile(\%apps, $configFilePath);

my %app_list = %apps;  # ive tried this in, out and in a variety of states

foreach my $name (sort keys %app_list) {
    print "\nMAIN $name";
}
# this is empty

ReadConfigFile.pm

sub readConfigFile (\%$) {
my ($apps_ref, $configFilePath) = @_;

# also tried 
# $apps_ref = shift but then configFilePath is empty
# linearray is each line from open config file split by :

$apps_ref{$lineArray[1]}{id} = $lineArray[1];
$apps_ref{$lineArray[1]}{name} = $lineArray[2];
$schema = $lineArray[1];
$directory = $lineArray[1];
$staticFile = $lineArray[1];

return ($schema, $directory, $staticFile);  

configFile.txt

APP:1101:ACTIVITY
APP:1102:EVENTS
APP:1103:PERFORMANCE
APP:1104:LOCATION
STATIC_FILE:static_file.sql
SCHEMA:CAASS
DIRECTORY:CAASS

我想返回3个标量变量和哈希值,这样我就可以在Main.pl中使用它们并传递给其他子程序。

我还尝试仅传入configfilename并返回4个变量,3个标量和哈希值。

我希望有人能在几分钟之内破解它,但我只是无法计算出\和@以及%和$的组合才能使其正常工作。

感谢您的帮助或想法。

编辑1: Main.pl

my %apps;
my ($schema, $directory, $staticFile) = readConfigFile(\%apps, $configFilePath);

foreach my $name (sort keys %apps) {
    print "\nMAIN $name";
}

ReadConfigFile

sub readConfigFile () {
my $apps_ref = shift;
my $configFilePath = $_[0];
#Fill It
$apps_ref{$lineArray[1]}{id} = $lineArray[1];
$apps_ref{$lineArray[1]}{name} = $lineArray[2];

# This shows results
foreach my $name (sort keys %apps_ref) {
    print "\nreadConfigFile   $name";
}

但是值不会回到Main.pl

编辑2: 因此,我仍然对如何使以上功能感兴趣。但是香港专业教育学院以不同的方式攻击它,而且有效

Main.pl

my ($schema, $directory, $staticFile, %apps) = readConfigFile($configFilePath);

foreach my $name (sort keys %apps) {
    print "\nMAIN $name";
}

ReadConfigFile

sub readConfigFile () {
my $configFilePath = $_[0];
my %apps;
#Fill It
%apps{$lineArray[1]}{id} = $lineArray[1];
$apps{$lineArray[1]}{name} = $lineArray[2];

foreach my $name (sort keys %apps) {
    print "\nreadConfigFile   $name";
}

return ($schema, $directory, $staticFile, %apps);

两者都会关闭输出显示。

1 个答案:

答案 0 :(得分:0)

Perl *中没有隐式的“通过引用传递”。一切都以相同的方式传递-作为标量列表,通过别名传递(因此传递哈希本身将传递其键和值的列表*)。但是您可以创建一个引用,将其传递,然后再取消引用以使用它-并且可以在不复制基础结构的情况下复制引用。

use strict;
use warnings;
my %hash;
my $ref = \%hash;
my $copy = $ref;
$copy->{a} = 1;
print "$ref->{a}\n"; # also 1

引用在子例程中进行my (...) = @_;my $foo = shift;分配后将保持其引用结构。

use strict;
use warnings;

sub foo {
  my ($ref, $key) = @_;
  $ref->{$key} = 42;
}

my %hash;
foo(\%hash, 'foo');
print "$hash{foo}\n"; # 42

有关Perl参考的相关文档,请参见https://p3rl.org/REF

由于您已经传递了引用,因此不需要(\%$)原型:您只需将其从子例程定义中删除即可。

*除了带有原型的样机外,但在大多数情况下最好避免使用它们。