我是Perl的新手,正在努力解决Llama书中的一些运动问题。问题是要编写一个子程序,如果他是第一个人,则欢迎一个人欢迎,或者告诉他前一个人的名字。我的代码看起来像:
#! perl
# This is the greeter problem .
sub greetPerson{
state $previous = undef ;
if($previous eq undef){
print " Welcome ... u r the first \n";
}
else{
print " Hi ... $previous was already here \n";
}
$previous = $_;
return 0;
}
@code = ("ravi" , "teja" , "chandu");
greetPerson($code[0]);
greetPerson($code[1]);
greetPerson($code[2]);
我收到错误说
"Can't call method state on undefined value in Line 6. "
请帮助我了解这意味着什么以及为什么要来解决它...? 据我所知,“state”与其他语言(C / Java)中的“static”同义。我错了吗?
答案 0 :(得分:9)
state
是一个相当新的功能(自Perl 5.10起),默认情况下未启用。启用它:
use feature 'state';
使用state
等同于在Java中使用静态变量。在没有状态的情况下执行此操作的另一种方法是使用$previous
之外的简单my
声明greetPerson
,这意味着它在整个脚本范围内。
顺便说一句,你还应该在所有脚本中包含这些行,以便在赛道上节省很多麻烦:
use strict;
use warnings;
此外,在greetPerson
中,您需要获取您的参数,您可以从@_
获取参数。 E.g。
my ($name) = @_; # or
my $name = $_[0];
答案 1 :(得分:2)
是;你有错误的东西(但我也是如此)。 AFAIK, state
在Perl中没有特定含义(但有人说这是一个必须启用的新功能)。
嗯... Perl 5.14.2有一个函数state
。它是在5.10.0中引入的;我已经检查了我的机器上的5.10.0版本,它就在那里,即使我没有意识到它。 DavidO有助于确认state
不属于5.8系列的Perl版本;该变化已在5.10.0中添加。
因此,您需要一个足够现代的Perl版本,您需要启用它:
use feature 'state';
如果未启用state
功能,它看起来像是一个方法调用,并且由于未定义该方法,您将看到错误。当然,即使启用它也是一个方法调用;或者,至少,它既被列为函数,也被描述为函数,但它是一个具有特殊语义的内置函数。
万一你没有意识到,StackOverflow的一个好处就是你通过回答问题来学习。
您可能正在寻找my
(或our
或local
,但这些不太可能。)
然而,当子程序退出时,子程序中的变量将消失,所以即使my
也不是你所追求的。
在没有state
的情况下,您可能会使用全局变量(没有任何初始化,因此在第一次传递时它的值为undef
):
my $previous;
在函数外部,然后您只需在函数中引用它:
sub greetPerson{
if ($previous eq undef){
print " Welcome ... u r the first \n";
}
else{
print " Hi ... $previous was already here \n";
}
$previous = $_[0];
return;
}
这也解决了$_
与传递给函数的参数无关的问题。你写作可能会更好:
sub greetPerson{
my($who) = @_;
if ($previous eq undef){
print " Welcome ... u r the first \n";
}
else{
print " Hi ... $previous was already here \n";
}
$previous = $who;
return;
}
您还应该使用use warnings;
和use strict;
。专家用它们来确保它们没有犯愚蠢的错误。新手也应该这样做。它确实意味着您必须声明所有变量。
关于state
的一个好处是,它允许你隐藏一个变量,否则该变量必须是全局的(或者如果你正在使用模块则隐藏在模块级别)所属。因此,了解它是一个有用的功能。
我正在传递一个标量
(@code[0])
。那么,为什么我需要在那里使用@_[0]
?$_
不是那个吗?但不知怎的,@_[0]
有效,而不是$_
......你能解释一下吗?
完整的故事很复杂,但Perl将参数传递给函数的方式是一个数组。在函数内部,参数在@_
中可用。变量$_
与@_
无关(除了名称的最后一个字符相同)。
注意:我修改了我的第一个示例以引用$_[0]
而不是@_[0]
。那就是访问@_
数组的第0个元素,但仍然与标量$_
无关。这是Perl确实引起混淆的一个领域。 (如果@_[0]
确实有效,那么要么我很幸运,要么有一些关于符号的Perl 6想法正在进入Perl 5.1x。)
随着时间的推移,你会习惯这种表示法:
sub some_name_or_other
{
my($arg1, $name2, $obj3, $ref4, $hash5, @the_rest) = @_;
...
}
这会将前5个参数分配给标量变量,并填充本地数组@the_rest
中遗留的任何内容。如果用参数太少来调用它,则会得到undef
个值。括号my(...)
列表是至关重要的。他们提供列表上下文并使其工作。省略括号,事情就会出错。但是,列表上下文比我想在这里详细讨论的主题更大;请查看Llama书(或骆驼书,或在线)了解详情。
如果您要引用该参数一次,承诺不更改该值,则可以使用$_[0]
表示法;如果您打算更频繁地使用它,请使用my
变量。无论如何,最好使用my
变量;它更易于理解。