В дополнение к уже упомянутому теги, необходимо также использовать
@code
аннотация JavaDoc, которая сделает жизнь намного легче когда дело доходит до проблем объектов HTML (в особенности с Дженериками), например:
*
* {@code
* Set s;
* System.out.println(s);
* }
*
даст корректный вывод HTML:
Set s;
System.out.println(s);
В то время как исключение @code
блок (или использование тег) приведут к HTML как это:
Set s;
System.out.println(s);
(Для ссылки, Java SE 8 описаний тега могут быть найдены здесь: Теги Javadoc )
Использование shift
для распаковки аргументов не является злом. Это обычное соглашение, которое может быть самым быстрым способом обработки аргументов (в зависимости от того, сколько их и как они передаются). Вот один пример довольно распространенного сценария, в котором это так: простой аксессор.
use Benchmark qw(cmpthese);
sub Foo::x_shift { shift->{'a'} }
sub Foo::x_ref { $_[0]->{'a'} }
sub Foo::x_copy { my $s = $_[0]; $s->{'a'} }
our $o = bless {a => 123}, 'Foo';
cmpthese(-2, { x_shift => sub { $o->x_shift },
x_ref => sub { $o->x_ref },
x_copy => sub { $o->x_copy }, });
Результаты perl 5.8.8 на моей машине:
Rate x_copy x_ref x_shift
x_copy 772761/s -- -12% -19%
x_ref 877709/s 14% -- -8%
x_shift 949792/s 23% 8% --
Не драматичны, но вот они. Всегда проверяйте свой сценарий на своей версии Perl на целевом оборудовании, чтобы узнать наверняка.
shift
также полезен в тех случаях, когда вы хотите отключить инвокант, а затем вызвать SUPER ::
, передав оставшиеся @_
как есть.
sub my_method
{
my $self = shift;
...
return $self->SUPER::my_method(@_);
}
Если бы у меня была очень длинная серия операций my $ foo = shift;
в верхней части функции, Однако, Вместо этого я мог бы рассмотреть возможность использования массовой копии из @_
. Но в целом, если у вас есть функция или метод, который принимает более нескольких аргументов, используя именованные параметры (т. Е. Перехват всех @_
в хэше % args
или ожидание один аргумент ссылки на хэш) - гораздо лучший подход.
Это, как и другие сказал, дело вкуса.
Я обычно предпочитаю переносить мои параметры в лексические, потому что это дает мне стандартное место для объявления группы переменных, которые будут использоваться в подпрограмме. Дополнительная многословность дает мне хорошее место для комментариев. Это также упрощает аккуратное предоставление значений по умолчанию.
sub foo {
my $foo = shift; # a thing of some sort.
my $bar = shift; # a horse of a different color.
my $baz = shift || 23; # a pale horse.
# blah
}
Если вас действительно беспокоит скорость вызова ваших подпрограмм, не делайте этого. t вообще распаковывать аргументы - обращаться к ним напрямую, используя @_
. Будьте осторожны, это ссылки на данные вызывающего абонента, с которыми вы работаете. Это обычная идиома в POE. POE предоставляет набор констант, которые вы используете для получения позиционных параметров по имени:
sub some_poe_state_handler {
$_[HEAP]{some_data} = 'chicken';
$_[KERNEL]->yield('next_state');
}
Теперь большая глупая ошибка, которую вы можете получить, если обычно распаковываете параметры со сдвигом, заключается в следующем:
sub foo {
my $foo = shift;
my $bar = shift;
my @baz = shift;
# I should really stop coding and go to bed. I am making dumb errors.
}
Я думаю, что согласованный стиль кода более важен чем какой-либо конкретный стиль. Если бы все мои коллеги использовали стиль назначения списков, я бы тоже использовал его.
Если бы мои коллеги сказали, что с использованием shift для распаковки возникла большая проблема, я бы попросил продемонстрировать, почему это плохо. Если корпус прочный, то кое-что узнаю. Если это подделка, я мог бы опровергнуть его и помочь остановить распространение анти-знания. Затем я' Я предлагаю определить стандартный метод и следовать ему в будущем коде. Я мог бы даже попытаться установить политику Perl :: Critic, чтобы проверить соответствие принятому стандарту.
Perl :: Critic - ваш друг. Он соответствует «стандартам», установленным в книге Дэмиана Конвея Perl Best Practices. Запуск с --verbose 11 дает вам объяснение того, почему все плохо. Не распаковывать @_ первым в ваших подпрограммах имеет степень серьезности 4 (из 5). Например:
echo 'package foo; use warnings; use strict; sub quux { my foo= shift; my (bar,baz) = @_;};1;' | perlcritic -4 --verbose 11
Always unpack @_ first at line 1, near 'sub quux { my foo= shift; my (bar,baz) = @_;}'.
Subroutines::RequireArgUnpacking (Severity: 4)
Subroutines that use `@_' directly instead of unpacking the arguments to
local variables first have two major problems. First, they are very hard
to read. If you're going to refer to your variables by number instead of
by name, you may as well be writing assembler code! Second, `@_'
contains aliases to the original variables! If you modify the contents
of a `@_' entry, then you are modifying the variable outside of your
subroutine. For example:
sub print_local_var_plus_one {
my ($var) = @_;
print ++$var;
}
sub print_var_plus_one {
print ++$_[0];
}
my $x = 2;
print_local_var_plus_one($x); # prints "3", $x is still 2
print_var_plus_one($x); # prints "3", $x is now 3 !
print $x; # prints "3"
This is spooky action-at-a-distance and is very hard to debug if it's
not intentional and well-documented (like `chop' or `chomp').
An exception is made for the usual delegation idiom
`$object->SUPER::something( @_ )'. Only `SUPER::' and `NEXT::' are
recognized (though this is configurable) and the argument list for the
delegate must consist only of `( @_ )'.
По своей сути это не зло, но его использование для получения аргументов подпрограммы один за другим сравнительно медленно и требует большего количества строк кода.
Имеется оптимизация для назначения списков.
Единственная ссылка, которую я смог найти, это этот .
5.10.0
случайно отключил оптимизация, которая вызвала измеримое падение производительности в списке назначение, такое как часто используется для назначить параметры функции из@_
. Оптимизация восстановлена, и исправлена регрессия производительности.
Это пример затронутой регрессии производительности.
sub example{
my($arg1,$arg2,$arg3) = @_;
}
Это не зло, это своего рода вкус. Вы часто будете видеть стили, используемые вместе:
sub new {
my $class = shift;
my %self = @_;
return bless \%self, $class;
}
Я обычно использую shift
, когда есть один аргумент или когда я хочу обрабатывать первые несколько аргументов иначе, чем остальные.
и
должны работать нормально, в Википедии есть Список предопределенных сущностей в XML .
sub do_another_thing {
my ($foo, $bar) = shift; # still 'works', but $bar not defined
}
, и они, возможно, внесли тонкую ошибку.
Назначение @_ может быть более компактным и эффективным с вертикальным пространством, когда у вас есть небольшое количество параметров для одновременного назначения. Это также позволяет вам указывать аргументы по умолчанию, если вы используете хэш-стиль именованных параметров функции
например
my (%arguments) = (user=>'defaultuser',password=>'password',@_);
Я все равно считаю это вопросом стиля / вкуса. Я считаю, что самое важное - применять тот или иной стиль последовательно, соблюдая принцип наименьшего удивления.
Это также позволяет вам указывать аргументы по умолчанию, если вы используете хэш-стиль именованных параметров функции, например,
my (%arguments) = (user=>'defaultuser',password=>'password',@_);
Я все равно считаю это вопросом стиля / вкуса. Я считаю, что самое важное - применять тот или иной стиль последовательно, соблюдая принцип наименьшего удивления.
Это также позволяет вам указывать аргументы по умолчанию, если вы используете хэш-стиль именованных параметров функциинапример
my (%arguments) = (user=>'defaultuser',password=>'password',@_);
Я все равно считаю это вопросом стиля / вкуса. Я думаю, что самое важное - применять тот или иной стиль последовательно, соблюдая принцип наименьшего удивления.
Я не думаю, что shift
- зло. Использование shift
показывает вашу готовность именовать переменные вместо использования $ _ [0]
.
Лично Я использую shift
, когда у функции только один параметр. Если у меня более одного параметра, я буду использовать контекст списка.
my $result = decode($theString);
sub decode {
my $string = shift;
...
}
my $otherResult = encode($otherString, $format);
sub encode {
my ($string,$format) = @_;
...
}