Jas*_*nds 0 perl parameter-passing subroutine
我正在将标量变量传递给子例程,在该子例程中我想测试参数是否与正则表达式匹配:
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";
}
}
Run Code Online (Sandbox Code Playgroud)
我收到输出有以下错误
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.
Run Code Online (Sandbox Code Playgroud)
我的想法是它将传递$name给"魔术变量" $_.我需要在多个<STDIN>变量上重用这个子例程.我该如何初始化$_?
你的子程序的参数不在$_.它在阵列中@_,你需要把它拿出来.
sub analyze_name {
my $name = shift; # implicitly shifts @_
if ($name =~ m/.../) { ... }
}
Run Code Online (Sandbox Code Playgroud)
或者作为列表分配
sub analyze_name {
my ($name) = @_;
....
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您想@_直接操作阵列
sub analyze_name {
if ($_[0] =~ m/.../) { ... }
}
Run Code Online (Sandbox Code Playgroud)
现在我们正在访问数组中的第一个元素@_.Perl中变量名称前面的符号(称为sigil)随着该表达式返回的值的类型而变化.所以对于数组来说@_,但是当你访问一个元素时,它变成$_[0]因为里面的值是标量,这意味着它只是一个值.这与$_标量变量不同.同样的事情是关于真@array,$array[4]并且标量变量$array(这是一个严重的选择的名称).
在大多数情况下,您希望执行shift或列表分配.如果您有两个或三个参数,则列表通常更容易阅读.如果有很多args,每行一个是有道理的.@_直接操作通常只有在速度成为问题时才有意义,因为您的子程序在您的程序中被调用了数百万次.我的建议是简洁地使用可读代码并使用正确命名的参数.
的$name在上面的代码是词法到该子程序.这意味着它只存在于那里,每次你调用那个sub,你就会得到一个新的$name.调用它时传入的变量的变量名称无关紧要.
analyze_name($foo);
analyze_name($bar);
analyze_name('foobar');
Run Code Online (Sandbox Code Playgroud)
所有这些都将值传递给sub.sub不关心变量名.在子,它总是$name.在子之外,$name不存在.
请注意,您不应该&在Perl中调用subs .这曾经是大约20年前Perl 4中的语法.在Perl 5中,这&foo()有一个你可能不想要的特殊含义.如果您想了解更多信息,请删除&并查找子例程原型.