初学者调用Perl子例程

时间:2010-12-18 20:14:48

标签: perl

我正在尝试自学Perl,我到处寻找可能是一个非常简单的问题的答案。我已经定义了一个子程序,我调用它来计算单词中的字母数。如果我这样写出来:

 $sentence="This is a short sentence.";

 @words = split(/\s+/, $sentence);

 foreach $element (@words) {
     $lngths .= length($element) . "\n";
 }
 print "$lngths\n";

然后它就像一个魅力。但是,如果我将其包装到子例程中,则拆分不会拆分输入,而是将整个句子计为单个输入。这是我如何定义子程序:

sub countWords {
    @words = split(/\s+/, @_);
    foreach $element(@words) {
        $lngths .= length($element) . "\n";
    }
    return $lngths;
}

从我阅读的所有页面和我所咨询过的文本中,这应该有效,但事实并非如此。

提前致谢!

3 个答案:

答案 0 :(得分:13)

问题在于您使用@_。这是一个数组,但你像标量一样访问它。

@_包含此函数的所有参数。它看起来的方式,你传递一个句子,你想分开它。以下是一些可能的方法:

@words = split(/\s+/, $_[0]);

表示“将第一个参数带入函数并将其拆分”。

或者:

my $sentence = shift;
@words = split(/\s+/, $sentence);

几乎相同,但使用中间变量来提高可读性。


事实上,你所做的是:

@words = split(/\s+/, @_);

这意味着:

  • @_解释为标量,表示@_中的数字元素(在本例中为1)
  • 按空格分割字符串"1"

返回数组:

@words = ("1");

答案 1 :(得分:3)

你得到了内森的答案的主要部分;剩下的观察是大多数人不把标点符号和数字都算作字母,但你的子程序呢。我可能会选择:

sub countLetters
{
    my($sentence) = @_;
    $sentence =~ s/[^[:alpha:]]//gm;
    return length($sentence);
}

这里的关键点是my子句中变量列表周围的括号。通常,您有几个参数传递给sub,您可以将它们分配(副本)到子例程中的变量,如下所示:

my($var1, $var2, $var3) = @_;

括号提供“列表上下文”并确保将@_的第一个元素复制到$var1,将第二个元素复制到$var2,依此类推。没有括号,您有'标量上下文',并且在标量上下文中计算数组时,返回的值是数组中元素的数量。因此:

my $var1, $var2, $var3 = @_;

可能会将3分配给$var1(因为有三个值传递给子例程),$var1$var2都是undef

正则表达式删除字符串中的所有非字母字符;字母数是剩下的长度。

答案 2 :(得分:0)

在计算字符时,perl的音译操作符通常会派上用场。 要计算非空白字符而不必将字符串拆分为单独的单词,您可以执行以下操作:

$lngths = $sentence =~ tr/ \t\f\r\n//c;