我将一个标量变量传递给我想测试参数是否与正则表达式匹配的子程序:
use strict;
use warnings;
use Data::Dumper;
print "Please enter your first name followed by your last name. For example: John Smith.\n";
chomp(my $name = <STDIN>);
&analyze_name($name);
sub analyze_name {
if ($_ =~ /^\w+\s+\w+$/) {
print "You entered $_.";
} else {
print "Incorrect convention";
}
}
我得到以下错误的输出
Please enter your first name followed by your last name. For example: John Smith.
firstname lastname
Incorrect convention
Use of uninitialized value $_ in pattern match (m//) at /home/jhusbands/scripts/examples/test.pl line 13, <STDIN> line 1.
我的想法是它会传递$name
给“魔法变量” $_
。我需要在多个<STDIN>
变量上重用这个子程序。如何初始化$_
?
子程序的参数不在$_
. 它在数组中@_
,您需要将其取出。
sub analyze_name {
my $name = shift; # implicitly shifts @_
if ($name =~ m/.../) { ... }
}
或者作为列表分配
sub analyze_name {
my ($name) = @_;
....
}
或者,如果你想@_
直接对数组进行操作
sub analyze_name {
if ($_[0] =~ m/.../) { ... }
}
现在我们正在访问数组中的第一个元素@_
。Perl 中变量名前面的符号(称为sigil)随着该表达式返回的值的类型而变化。所以对于数组它是@_
,但是当你访问一个元素时,它变成了$_[0]
因为里面的值是标量,这意味着它只有一个值。这不同于$_
,后者是一个标量变量。同样的事情也适用于@array
,$array[4]
和标量变量$array
(这是一个错误选择的名称)。
在大多数情况下,您想要执行shift
或 列表分配。如果您有两个或三个参数,则列表通常更易于阅读。如果有很多 args,每行一个是有意义的。@_
直接操作通常只有在速度有问题时才有意义,因为您的 sub 在您的程序中被调用了数百万次。我的建议是采用简洁易读的代码并使用正确命名的参数。
的$name
在上面的代码是词法到该子程序。这意味着它只存在于那里,每次你调用那个 sub 时,你都会得到一个新的$name
. 调用时传入的变量的变量名无关紧要。
analyze_name($foo);
analyze_name($bar);
analyze_name('foobar');
所有这些都将一个值传递给 sub。sub 不关心变量名。在 sub 中,它总是$name
. 子之外,$name
不存在。
请注意,您不应&
在 Perl 中使用 with 调用 subs 。大约 20 年前,这曾经是 Perl 4 中的语法。在 Perl 5 中,这&foo()
具有您可能不想要的特殊含义。如果您想了解更多信息,请删除&
, 并查找子程序原型。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句