将散列传递给子程序

问题描述 投票:0回答:3

我正在为自己开发一个项目,在将哈希传递给子例程时遇到了问题。实际上有几个子例程,但是我试图将其简化到最低限度。我意识到%mdc是全局哈希,因此我不必将其传递给我拥有的所有子例程,但是出于习惯,我宁愿使用它。尽管下面的代码片段确实可以正常工作,但是感觉好像更干净。

无论如何,我认为必须有更好的方法的部分是线条:

%mdc_def = mysub(\%mdc);
%mdc = %$mdc_def;

感觉……对我来说很笨拙,但我没有找到一种方法使这两行只是一条...类似(尽管语法很差):

%mdc = %mysub(\%mdc);

然后,如果我应该有一个mysub2,它也需要该哈希,那么我也必须在该子例程中进行相同的两行随机播放。感觉很乱。

这是我正在研究的代码段:

use strict;
use warnings;

my %mdc = ();
my $mdc_def;

$mdc{abc} = 123;
$mdc{cde} = 234;

foreach (sort keys (%mdc)) { print "before $_ = $mdc{$_}\n"; }
$mdc_def = mysub(\%mdc);
%mdc = %$mdc_def;
foreach (sort keys (%mdc)) { print " after $_ = $mdc{$_}\n"; }

sub mysub {
  my ($mdc_def) = @_;
  my %m = %$mdc_def;

  $m{def} = 345;
  $m{efg} = 456; 

  return \%m;
}

提前感谢。

perl hash subroutine
3个回答
0
投票

您是否了解$hash_ref = \%hash是什么以及如何使用它?

use strict;
use warnings;
use feature 'say';

my %mdc = ();

$mdc{abc} = 123;
$mdc{cde} = 234;

say '- Before ------------';

while( my($k,$v) = each %mdc ) {
    say "$k => $v";
}

mysub(\%mdc);

say '- After -------------';

while( my($k,$v) = each %mdc ) {
    say "$k => $v";
}

sub mysub {
  my $mdc_ref = shift;

  $mdc_ref->{def} = 345;
  $mdc_ref->{efg} = 456; 
}

输出

- Before ------------
cde => 234
abc => 123
- After -------------
def => 345
cde => 234
abc => 123
efg => 456

0
投票

您可以使用以下内容:

sub mysub {
   my ($mdc_def) = @_;
   my %m = %$mdc_def;

   $m{def} = 345;
   $m{efg} = 456; 

   return \%m;
}

my %mdc = ( a=>1, b=>2 );

%mdc = %{ mysub(\%mdc) };

但是,这不会使哈希表和其中的所有标量一两无用。没有理由将全局变量设为哈希而不是标量,这样可以避免复制实例之一。

sub mysub {
   my ($mdc_def) = @_;
   my %m = %$mdc_def;

   $m{def} = 345;
   $m{efg} = 456; 

   return \%m;
}

my $mdc = { a=>1, b=>2 };

$mdc = mysub(\%mdc);

剩下一个复制实例。如果您不希望mysub就地修改哈希,则需要该实例,因此上面的代码很好。

以下版本修改了哈希值,避免了第二个复制实例(并允许我们将全局变量保留为哈希值)。

sub mysub_inplace {
   my ($mdc_def) = @_;
   $mdc->{def} = 345;
   $mdc->{efg} = 456; 
}

my %mdc = ( a=>1, b=>2 );

mysub_inplace(\%mdc);

0
投票

尝试

%mdc = %{mysub(\%mdc)};
  • [\%mdc会将对%mdc哈希的引用作为参数传递给mysub suroutine
  • %{mysub(…)}将mysub调用的返回值视为哈希引用并将其转换为哈希

您可以使用子例程原型sub mysub (\%)来通过mysub(%mdc)调用mysub


简单的示例/脚本:

#!/usr/bin/perl
# Original version constained prototypes for sub mysub - 
# see ikegami comments below the answear
use strict;
use warnings;

sub mysub {
  my( $hRef ) = (@_);
  $hRef->{a} = 0;
  $hRef->{c} = 3;
  return $hRef;
}

my %mdc = ( a=>1, b=>2);

%mdc = %{mysub(\%mdc)};
print %mdc;
© www.soinside.com 2019 - 2024. All rights reserved.