Стиль передачи параметров в Perl - PullRequest
6 голосов
/ 30 июля 2010

Я вижу людей, использующих два стиля для передачи именованных параметров в Perl:

use strict;
use warnings;
use Data::Dumper;

sub foo {
    print Dumper @_;
}

sub bar {
    print Dumper @_;
}

foo( A => 'a', B => 'b' );
bar( { A => 'a', B => 'b' } );

Каковы преимущества использования стиля foo () вместо стиля bar () ?

Ответы [ 3 ]

9 голосов
/ 30 июля 2010

Второй метод передает ссылку на хеш, тогда как первый просто передает список.

Здесь есть два аспекта: теоретически, ссылка на хеш может быть лучше с точки зрения производительности, хотя для краткостисписки аргументов это незначительно.Для простого вызова, такого как foo(a => 1, b => 2), разницы в производительности нет, поскольку @_ фактически является псевдонимом исходных значений.

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

Второй аспект - это вопрос, кто отвечает за преобразование в хеш.Первый стиль оставляет за собой вызываемую функцию, и если он просто делает my %args = @_, он выдаст любопытные предупреждения, если список аргументов не будет четной длины.

Вот почему я немного предпочитаю второй стиль (или я использую Perl 6, который изначально поддерживает именованные аргументы).

6 голосов
/ 30 июля 2010

Стиль foo(a => 1, b => 2) - это обычный способ эмуляции именованных аргументов.bar({a => 1, b => 2}) обычно используется только для дополнительных (и, возможно, необязательных) аргументов.

Для типичного использования я предпочитаю первую форму.{} - это дополнительный набор текста, дополнительный шум при чтении и возможная ошибка, если вы пропустите одну или обе скобки.Любая разница в производительности незначительна.(Если это не так, у вас есть большие проблемы.) С другой стороны, оборачивание аргументов в анонимном хеш-конструкторе может помочь вам найти ошибки во время компиляции, а не во время выполнения.с позиционными аргументами.например, Benchmark делает это:

cmpthese(10000, {
    foo => \&foo,
    bar => \&bar,
});

Пока Tk оставляет {} вне:

my $text = $w->Scrolled('Text', -width => 80, -height => 50);

Обычно это стилистический выбор.

5 голосов
/ 30 июля 2010

Во-первых, объяснение двух методов:

sub foo {
    # Transform the array to a hash
    my %args = @_;

    foreach my $key ( keys %args ) {
        print "$key => $args{$key}\n";
    }
}

# Pass an array of values
foo( A=>'a', B=>'b' );

В этом первом случае все, что вы делаете, это передаете массив.=> в этом контексте не является индикатором хэш-ключа / значения, о котором вы могли бы подумать.В этом контексте это просто «толстая запятая».

sub bar {
    my ($hash_ref) = @_;
    foreach my $key ( keys %$hash_ref ) {
        print "$key => $hash_ref->{$key}\n";
    }
}

# pass a ref to an anonymous hash
bar( { A=>'a', B=>'b' } );

Во втором случае вы создаете анонимный хеш и передаете ссылку на этот хеш в качестве аргумента функции.

Зачем выбирать один над другим?В книге Perl Best Practices, глава 9 под заголовком «Именованные аргументы», автор рекомендует использовать второй стиль, когда для функции имеется более трех аргументов.Он также предпочитает это, потому что он ловит несоответствующее количество аргументов во время компиляции, а не во время выполнения.

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