【问题标题】:Can I pass mix type of optional arguments to a subroutine?我可以将混合类型的可选参数传递给子例程吗?
【发布时间】:2019-02-09 04:07:48
【问题描述】:

我正在尝试将散列和可选变量列表传递给散列中的子例程,但它不起作用。您能否更正以下示例代码以帮助我解决此问题?

我的示例代码如下所示

#!/bin/env perl
use warnings;
use strict;
use Data::Dumper;
my %h1 = ( a=> 2, b=>3);
sub sum {
   my $var1=shift;
   my $var2=shift;

   my %hash1=@_;
   #my($a,$b)=@_;
   my $i=0;
   foreach my $val (keys %hash1) {
        $i=$i+$hash1{$val};
   }
   if ( not defined $var2 ) {
        return ($i+$var1);
   } else {
        return ($i+$var1+$var2);
   }
}
my $c=sum(3,%h1);
print $c;

【问题讨论】:

  • 一般建议:始终use strict;。不要调用你的变量$a$b(它们在sort 中有特殊含义)。不要用&调用子程序。
  • 不是完全重复,而是相似:stackoverflow.com/questions/8481405/…
  • 感谢 Melpomene。我已根据您的建议更新了代码。因为它只是一个示例代码,所以我不关心严格的功能。
  • 因为它只是一个示例代码,所以我不关心严格的功能这绝不是一个好主意:-)
  • 谢谢戴夫。我正在寻找一种使用 perl 子例程通过散列传递可选参数的方法。我让它工作了,这里是我的示例代码

标签: perl hash subroutine


【解决方案1】:

你这样调用你的子程序:

my $c=sum(3,%h1);

在您的子程序中,您可以像这样访问参数:

   my $var1=shift;
   my $var2=shift;

   my %hash1=@_;

这里似乎有一个明显的差异。您将一个标量和一个散列传递给子例程,但在您的子例程中,您需要 两个 标量和一个散列。

因此,如果您删除 my $var2 = shift 行,它可能会按照您的预期工作。

您的子例程要做什么并不是很清楚。如果您要解释这一点,那么我们可能会提供更多帮助。

更新:您的代码中有Data::Dumper。为什么不使用它来尝试了解正在发生的事情。

print Dumper(\@_), "\n";
my $var1=shift;
my $var2=shift;

my %hash1=@_;
print Dumper($var1, $var2, \%hash1), "\n";

我明白了:

$VAR1 = [
          3,
          'b',
          3,
          'a',
          2
        ];

Odd number of elements in hash assignment at test line 11.
$VAR1 = 3;
$VAR2 = 'b';
$VAR3 = {
          '3' => 'a',
          '2' => undef
        };

这显示了一些有趣的事情:

  • 在放入 @_ 之前,已将哈希“展开”到列表中。
  • 从具有奇数个元素的列表中初始化哈希时收到的警告。
  • 您的 %hash1 变量的键和值不正确。

【讨论】:

  • 谢谢戴夫。我正在寻找一种使用 perl 子例程通过散列传递可选参数的方法。我让它工作了,这里是我的示例代码
【解决方案2】:

谢谢大家。这就是我们如何将可选参数传递给 perl 中混合类型的子例程

#!/bin/env perl
use warnings;
use strict;
use Data::Dumper;
my %h1 = ( a=> 2, b=>3); 
sub sum {

   my ($hash1,$var1,$var2)=@_;
   #my($a,$b)=@_;
   my $i=0;
   foreach my $val (keys %{$hash1}) {
   $i=$i+$hash1->{$val};
   }
   if (defined $var2 ) {
    return ($i+$var1+$var2);
   } else {
    return ($i+$var1);
   }
}

my $c=sum(\%h1,3);
print $c;

如果我遗漏了什么,请纠正我。

问候, 潜水

【讨论】:

  • 所以您已经了解到 a) 可选参数位于参数列表的末尾,并且 b) 最好将散列和数组作为引用传递给子例程。
【解决方案3】:
#!/usr/bin/perl
use warnings;
use strict;
use JSON;
use feature qw(say);

args_in( 'test', { foo => 'bar' }, ["one", "two", "three"] );

sub args_in {
  my $args_aref = parse_args( @_ );
  say to_json $args_aref;
}

sub parse_args {
  my @ary;
  foreach( @_ ) {
    my %hash;
    if (ref $_) {
      $hash{type} = ref $_;
    } else {
      $hash{type} = 'SCALAR';
    }
    $hash{value} = $_;
    push @ary, \%hash;
  }
  return \@ary;
}

结果:

[
    {
        "value": "test",
        "type": "SCALAR"
    },
    {
        "value": {
            "foo": "bar"
        },
        "type": "HASH"
    },
    {
        "value": [
            "one",
            "two",
            "three"
        ],
        "type": "ARRAY"
    }
]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 2013-01-05
    • 1970-01-01
    相关资源
    最近更新 更多