在 Perl 中,如何将变量作为参数传递给子例程?
In Perl, how can I pass a variable as an argument to a 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";
}
}
我收到以下错误的输出
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
传递给 "magic variable" $_
。我需要在多个 <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)随该表达式 returns 的值类型而变化。所以对于数组来说它是@_
,但是当你访问一个元素时,它变成了$_[0]
,因为里面的值是标量,这意味着它只有一个值。这与 $_
不同,它是一个标量变量。 @array
、$array[4]
和标量变量 $array
(这是一个错误的名称)也是如此。
在大多数情况下,您想要执行 shift
或列表分配。如果您有两个或三个参数,列表通常更容易阅读。如果有很多参数,每行一个是有意义的。直接在 @_
上操作通常只有在速度是个问题时才有意义,因为你的子程序在你的程序中被调用了数百万次。 我的建议是代码可读性高于简洁性,并使用正确命名的参数。
上面代码中的$name
是那个子程序的词法。这意味着它只存在于那里,每次你调用那个 sub 时,你都会得到一个新的 $name
。调用时传入的变量的变量名无所谓
analyze_name($foo);
analyze_name($bar);
analyze_name('foobar');
所有这些都将值传递给 sub。 sub 不关心变量名。在 sub 中,它总是 $name
。在 sub 之外,$name
不存在。
请注意,您不应在 Perl 中使用 &
调用 subs。这曾经是大约 20 年前 Perl 4 中的语法。在 Perl 5 中,这个 &foo()
有一个你可能不想要的特殊含义。删除 &
,然后查找 子程序原型 如果您想了解更多相关信息。
如果您只想让您的代码正常工作,您需要更改:
if ($_ =~ /^\w+\s+\w+$/) {
到
if ($_[0] =~ /^\w+\s+\w+$/)
{
与 perl
一起安装的 Perl 文档 perldoc perlsub 说:
Any arguments passed in show up in the array @_ .
...
if you called a
function with two arguments, those would be stored in $_[0]
and $_[1]
. The array @_ is a local array, but its elements are aliases for the
actual scalar parameters.
相反,我建议您将参数存储到变量中,并避免使用“&”调用子例程,正如 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";
}
}
我正在将标量变量传递给子例程,我想在其中测试参数是否与正则表达式匹配:
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
传递给 "magic variable" $_
。我需要在多个 <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)随该表达式 returns 的值类型而变化。所以对于数组来说它是@_
,但是当你访问一个元素时,它变成了$_[0]
,因为里面的值是标量,这意味着它只有一个值。这与 $_
不同,它是一个标量变量。 @array
、$array[4]
和标量变量 $array
(这是一个错误的名称)也是如此。
在大多数情况下,您想要执行 shift
或列表分配。如果您有两个或三个参数,列表通常更容易阅读。如果有很多参数,每行一个是有意义的。直接在 @_
上操作通常只有在速度是个问题时才有意义,因为你的子程序在你的程序中被调用了数百万次。 我的建议是代码可读性高于简洁性,并使用正确命名的参数。
上面代码中的$name
是那个子程序的词法。这意味着它只存在于那里,每次你调用那个 sub 时,你都会得到一个新的 $name
。调用时传入的变量的变量名无所谓
analyze_name($foo);
analyze_name($bar);
analyze_name('foobar');
所有这些都将值传递给 sub。 sub 不关心变量名。在 sub 中,它总是 $name
。在 sub 之外,$name
不存在。
请注意,您不应在 Perl 中使用 &
调用 subs。这曾经是大约 20 年前 Perl 4 中的语法。在 Perl 5 中,这个 &foo()
有一个你可能不想要的特殊含义。删除 &
,然后查找 子程序原型 如果您想了解更多相关信息。
如果您只想让您的代码正常工作,您需要更改:
if ($_ =~ /^\w+\s+\w+$/) {
到
if ($_[0] =~ /^\w+\s+\w+$/)
{
与 perl
一起安装的 Perl 文档 perldoc perlsub 说:
Any arguments passed in show up in the array @_ . ... if you called a function with two arguments, those would be stored in
$_[0]
and$_[1]
. The array @_ is a local array, but its elements are aliases for the actual scalar parameters.
相反,我建议您将参数存储到变量中,并避免使用“&”调用子例程,正如 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";
}
}