Начинающий вызывает подпрограмму Perl - PullRequest
2 голосов
/ 18 декабря 2010

Я пытаюсь научить себя 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 ]

13 голосов
/ 18 декабря 2010

Проблема в том, что вы используете @_.Это массив, но вы обращаетесь к нему как скаляр.

@_ содержит все параметры этой функции.Как это выглядит, вы передаете это предложение, и вы хотите разделить его.Вот несколько возможных способов сделать это:

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

, что означает «взять первый параметр в функцию и разделить его».

Или:

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

Это почти то же самое, но для удобства чтения используется промежуточная переменная.


На самом деле вы делаете следующее:

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

Что означает:

  • интерпретировать @_ как скаляр, что означает число элементов в @_ (в данном случае 1)
  • разбить строку "1" на пробельные символы

, который возвращает массив:

@words = ("1");
3 голосов
/ 19 декабря 2010

У вас есть основная часть ответа от Натана;остаточное наблюдение состоит в том, что большинство людей не считают знаки препинания и цифры буквами, а ваша подпрограмма это делает.Я бы, наверное, пошел с:

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

Ключевым моментом здесь являются круглые скобки вокруг списка переменных в предложении my.Как правило, в подпрограмму передается несколько аргументов, и вы можете назначать (копировать) их переменным в вашей подпрограмме следующим образом:

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

Скобки обеспечивают «контекст списка» и гарантируют, что первыйэлемент @_ копируется в $var1, второй в $var2 и так далее.Без скобок у вас есть «скалярный контекст», а когда массив оценивается в скалярном контексте, возвращаемое значение является количеством элементов в массиве.Таким образом:

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

, скорее всего, назначит 3 для $var1 (поскольку три подпрограммы были переданы в подпрограмму), а $var1 и $var2 оба будут undef.

Регулярное выражение удаляет все не алфавитные символы из строки;количество букв - это длина того, что осталось.

0 голосов
/ 19 декабря 2010

При подсчете символов часто полезен оператор транслитерации perl.Чтобы подсчитать непробельные символы без необходимости разбивать строку на отдельные слова, вы можете сделать:

$lngths = $sentence =~ tr/ \t\f\r\n//c;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...