【问题标题】:Perl: return an array from subroutinePerl:从子程序返回一个数组
【发布时间】:2017-06-19 18:01:24
【问题描述】:

Perl 菜鸟。

我无法理解从模块中的子例程返回数组值。

脚本有以下内容:

print "Enter your first and last name.\n";
    chomp(my $fullname = <STDIN>); #input is 'testing this' all lower case

Jhusbands::Loginpass->check_name($fullname);

print "$fullname\n";

该模块包括以下子程序:

sub check_name {
    my $class = shift;
    if ($_[0] =~ /^\w+\s+\w+$/ ) {
        @_ = split( / /, $_[0]);

            foreach $_ (@_) {
                $_ = ucfirst lc for @_;
                @_ = join(" ", @_);
                print Dumper(@_) . "\n";
                return @_;
            }
      }   
}

我正在取名字,只检查它的第一个和最后一个(我稍后会谈到 else 语句),拆分它,更正大小写,然后再次加入。 Dumper 将最终数组显示为:

$VAR1 = 'Testing This';

所以它似乎工作得那么远。但是,脚本中 $fullname 的返回值显示全部小写:

测试这个

为什么不将 Dumper 显示的更正后的大写变量作为最后一次数组迭代?

【问题讨论】:

  • 你正在从你的 sub 返回一个但没有将它存储在任何地方。
  • 另外,foreach $_ (@_) { ... } 应该只替换为 ...
  • 你应该使用@_以外的数组。
  • Dumper(@a) 应该是Dumper(\@a)

标签: perl return-value subroutine data-dumper


【解决方案1】:

您不会将收益分配给任何东西。此外,子操纵 @_ 它不应该这样做,如下所述。也可以大大简化

sub check_name {
    my ($class, $name) = @_;

    if ($name =~ /^\w+\s+\w+$/) {
        return join ' ', map { ucfirst lc } split ' ', $name;
    }

    return;  # returns "undef" (as input wasn't in expected format)    
}

然后调用者可以做

my $fullname = Jhusbands::Loginpass->check_name($name);

print "$fullname\n" if $fullname;

应始终检查 sub 的返回,但在这种情况下更是如此,因为它有条件地处理其输入。为了清楚起见,我将输入重命名为 sub($name)。

如果子代码中的代码旨在通过直接写入@_ 来更改$fullname(并且您因此没有返回),那么由于在特定操作之后$_[0] 不再是别名为传递的参数。

无论如何,这样做非常棘手,可能导致代码不透明——而且是不必要的。要直接更改参数,请将其作为引用传递并写入。但是,在这种情况下,返回结果可能更清晰,更不容易出错。


应该注意的是,上面的名称“处理”遇到了名称处理的标准问题,因为它们令人眼花缭乱。如果这需要全面,则应将名称解析分派到可以处理可能的混乱的圆形库(或过程)。

感谢ikegami cmets 提供了示例以及更直接的方法:

$name =~ s/(\w+)/\u\L$1/g; 
return $name;

在v5.14中引入/r可以写成

return $name =~ s/(\w+)/\u\L$1/gr;

如果 $name 没有单词字符 (\w) 并且没有匹配项,则返回相同的字符串。

【讨论】:

  • 你在 exact 相同的解决方案上领先我一秒(除非我返回 $name,如果 if 不匹配;)++
  • 不管怎样,他们都破坏了Foo LeBlancBar von BraunBaz Hansen-Sinfield
  • @ikegami 谢谢,添加到答案中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-19
  • 2018-03-24
  • 1970-01-01
相关资源
最近更新 更多