Я не знаю, как устанавливать аргументы по умолчанию для подпрограмм. Вот что я подумал:
sub hello {
print @_ || "Hello world";
}
Это отлично работает, если все, что вам нужно, - это один аргумент. Как бы вы установили значения по умолчанию для нескольких аргументов?
Я собирался сделать это:
sub hello {
my $say = $_[0] || "Hello";
my $to = $_[1] || "World!";
print "$say $to";
}
Но это много работы ... Должен быть способ попроще; возможно, лучший метод?
Я делаю это с такими именованными аргументами:
sub hello {
my (%arg) = (
'foo' => 'default_foo',
'bar' => 'default_bar',
@_
);
}
Я считаю, что Params :: Validate поддерживает значения по умолчанию, но это больше проблем, чем мне хотелось бы.
Обычно я делаю что-то вроде:
sub hello {
my ($say,$to) = @_;
$say ||= "Hello";
$to ||= "World!";
print "$say $to\n";
}
Обратите внимание, что, начиная с perl 5.10, вы можете использовать оператор « // =
», чтобы проверить, определена ли переменная, а не просто ненулевое значение. (Представьте себе звонок hello ("0", "friend")
, который при использовании вышеуказанного даст "Hello friend"
, что может быть не тем, что вы хотели. Использование ] // =
оператор вернет «0 друг»
).
Если вы посмотрите документацию Perl Best Practices : Значения аргументов по умолчанию от Damian Conway , то вы найдете несколько важных указывает, например:
Пример:
#!/usr/bin/perl
use strict;
use warning;
my %myhash = (say => "Hello", to => "Stack Overflow");
sub hello {
my ($say, $to) = @_;
$say = $say ? $say : $myhash{say};
$to = $to ? $to : $myhash{to};
print "$say $to\n";
}
hello('Perl'); # output :Perl Stack Overflow
hello('','SO'); # output :Hello SO
hello('Perl','SO'); # output :Perl SO
hello(); # output :Hello Stack Overflow
Более подробный и полный пример см. В Perl Best Practices .
Attribute :: Default модуль на CPAN. Вероятно, чище, чем это, и позволяет избежать некоторых сложностей (например, что, если вы хотите передать false
своей подпрограмме?).
Я также видел, как люди использовали my $ var = exists @_ [0]? shift: "Default_Value";
, но в документации Perl отмечается, что вызов существует
в массивах устарел , поэтому я бы не рекомендовал его.
Фрагмент Attribute :: Default
со страницы документа:
sub vitals : Default({age => 14, sex => 'male'}) {
my %vitals = @_;
print "I'm $vitals{'sex'}, $vitals{'age'} years old, and am from $vitals{'location'}\n";
}
# Prints "I'm male, 14 years old, and am from Schenectady"
vitals(location => 'Schenectady');
Для получения дополнительной информации см. Также Method :: Signatures :
func add($this = 23, $that = 42) {
return $this + $that;
}
Поскольку Perl-механизм передачи аргументов подпрограммам представляет собой единый список, аргументы позиционны. Это затрудняет предоставление значений по умолчанию. Некоторые встроенные модули (например, substr
) обрабатывают это, упорядочивая аргументы в соответствии с вероятностью их использования - менее часто используемые аргументы появляются в конце и имеют полезные значения по умолчанию.
Более простой способ сделать это - использовать именованные аргументы. Perl не поддерживает именованные аргументы как таковые , но вы можете имитировать их с помощью хешей:
use 5.010; # for //
sub hello {
my %arg = @_;
my $say = delete $arg{say} // 'Hello';
my $to = delete $arg{to} // 'World!';
print "$say $to\n";
}
hello(say => 'Hi', to => 'everyone'); # Hi everyone
hello(say => 'Hi'); # Hi world!
hello(to => 'neighbor Bob'); # Hello neighbor Bob
hello(); # Hello world!
Примечание: оператор defined-or //
был добавлен в Perl v5.10. Это более надежно, чем использование логического ИЛИ ( ||
), поскольку оно не будет по умолчанию для логически ложных значений ''
и 0
.
Лучший способ решения вашей проблемы обсуждался в других ответах.
Однако меня поразило то, что вы утверждаете следующее:
sub hello { печать @_ || "Привет мир"; }
И это отлично работает, если вам нужен только один аргумент.
Вы действительно пробовали этот код? Он напечатает количество аргументов или, если они не указаны, Hello World
!
Причина этого в том, что || -оператор имеет приоритет и заставляет левую часть в скалярном контексте, таким образом уменьшая @_
до количества аргументов, которые вы предоставляете, а НЕ самих аргументов!
посмотрите perlop для получения дополнительной информации об операторах в Perl.
HTH,
Пол
Также взгляните на Метод::Подписи
. Здесь используется Devel::Declare
для предоставления дополнительного (необходимого!) сахара с ключевыми словами method
и func
.
Ниже приведен пример использования новой функции
:
use Method::Signatures;
func hello ($say='Hello', $to='World!') {
say "$say $to";
}
hello( 'Hello', 'you!' ); # => "Hello you!"
hello( 'Yo' ); # => "Yo World!"
hello(); # => "Hello World!"
/I3az/