2017-06-14 84 views
0

我传递一个标量子程序中,我想测试如果参数一个正则表达式匹配:在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>变量上重用此子例程。我如何初始化$_

回答

5

您的子程序的参数不在$_。它在数组@_中,你需要把它弄出来。

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()有一个特殊的含义,你可能不想要。如果你想知道更多关于&,并寻找子程序原型

+1

事实上,*伟大*! –

0

如果你只是想你的代码工作,你需要改变:

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"; 
    } 
} 
相关问题