在Perl中,如何将变量作为参数传递给子例程?
我传递一个标量子程序中,我想测试如果参数一个正则表达式匹配:在Perl中,如何将变量作为参数传递给子例程?
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
或列表分配。如果您有两个或三个参数,则列表通常更易于阅读。如果有很多参数,每行有一个是合理的。直接运行@_
通常只有在速度问题时才有意义,因为您的子程序在程序中被调用了数百万次。 我的建议是在简洁的情况下读取可读代码,并使用正确命名的参数。
在上面的代码的$name
是词法到该子程序。这意味着它只存在于那里,每次你打电话给你时,你会得到一个新的$name
。您调用时传入的变量的变量名称无关紧要。
analyze_name($foo);
analyze_name($bar);
analyze_name('foobar');
所有这些将值传递给子。该子程序不关心变量名称。在分中,它总是$name
。在子之外,$name
不存在。
请注意,您不应该在Perl中使用&
来调用subs。过去大约20年前,它曾经是Perl 4中的语法。在Perl 5中,这个&foo()
有一个特殊的含义,你可能不想要。如果你想知道更多关于&
,并寻找子程序原型。
如果你只是想你的代码工作,你需要改变:
if ($_ =~ /^\w+\s+\w+$/) {
要
if ($_[0] =~ /^\w+\s+\w+$/)
{
Perl的文档,perldoc perlsub安装了一起perl
,说:
传入的任何参数都显示在数组@_中。 ... 如果您使用两个参数调用 函数,那些函数将存储在
$_[0]
和$_[1]
中。数组@_是一个本地数组,但其元素是 实际标量参数的别名。
不要使用此,我建议您将参数存储到一个变量,也避免调用子程序与“&”为simbabque在他回答说,等:
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 {
my ($name) = @_;
if ($name =~ /^\w+\s+\w+$/) {
print "You entered $name.";
} else {
print "Incorrect convention";
}
}
事实上,*伟大*! –