Как я могу сделать функции Perl, которые по умолчанию используют $ _? - PullRequest
4 голосов
/ 02 декабря 2009

Итак, у меня есть массив и простая функция, которая обрезает пробелы:

my @ar=("bla ", "ha  1")
sub trim { my $a=shift; $a =~ s/\s+$//; $a}

Теперь я хочу применить это к массиву с помощью функции map. Почему я не могу сделать это, просто указав имя функции, как это было бы со встроенными функциями?

например. Вы можете сделать

print map(length,@ar)

но вы не можете сделать

print map(trim,@ar)

вы должны сделать что-то вроде:

print map {trim($_)} @ar
print map(trim($_),@ar)

Ответы [ 4 ]

12 голосов
/ 02 декабря 2009

Если вы используете 5.10 или более позднюю версию, вы можете указать _ в качестве прототипа для trim. Если вы используете более ранние версии, используйте ответ Axeman :

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

use strict; use warnings;

my @x = ("bla ", "ha  1");

sub trim(_) { my ($x) = @_; $x =~ s!\s+$!!; $x }

print map trim, @x;

Кстати, не используйте $a и $b вне компаратора sort: они защищены от проверки strict.

Однако я предпочитаю не использовать прототипы для функций, которые я пишу, в основном потому, что их использование затрудняет умственный анализ кода. Итак, я бы предпочел использовать:

map trim($_), @x;

См. Также perldoc perlsub :

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

7 голосов
/ 02 декабря 2009

Прототип, о котором говорит Синан, - лучший из существующих способов. Но для более ранних версий есть еще старый резерв:

sub trim { 
    # v-- Here's the quick way to do it.
    my $str = @_ ? $_[0] : $_;
    # That was it.

    $str =~ s/^\s+|\s+$//;
    return $str;
 }

Конечно, у меня есть trim функция с большим количеством функций, которая обрабатывает больше аргументов и список контекста, но она также не демонстрирует концепцию. Тернарное выражение - это быстрый способ сделать то, что сейчас делает символ-прототип '_'.

... Кстати, правила Perl!

3 голосов
/ 04 декабря 2009

Мой любимый способ использования $ _ без 5.10+ заключается в следующем:

sub trim {
    my ($s) = (@_, $_);
    $s =~ s/\s+$//;
    $s
}

это присваивает первый элемент @_ $ s, если он есть, в противном случае используется $ _

0 голосов
/ 02 декабря 2009

Многие встроенные функции Perl работают с $ _, если не заданы аргументы.

Если ваша функция делает то же самое, она будет работать:

my @ar=("bla ", "ha  1");
sub trim { my $s=@_?$_[0]:$_;$s =~ s/\s+$//; $s}
print map(trim,@ar),"\n";

И да, Perl довольно грубый.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...