2015-07-31 6 views
2

Изначально мой код выглядел так:Условно экземпляр нового массива Perl

my @departments = @{$opts->{'d'}} if $opts->{'d'}; 

Я хотел реорганизовать заявление в линии if согласно Perl Best Practices, так что теперь у меня есть следующий код:

my @departments; 
if($opts->{'d'}) 
{ 
    @departments = @{$opts->{'d'} }; 
} 

$opts - это просто хеш-ссылка, которая может иметь массив ref как значение ключа.

Я хотел бы сделать что-то вроде следующего, чтобы сохранить код на одной строке:

my @departments = $opts->{'d'} ? @{$opts->{'d'}} : undef; 

Но очевидно, что будет просто поставить один элемент в @departments со значением undef.

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

if(@departments) 
{ 
    my $department_string = join(q{,}, @departments); 
    $big_string . $department_string; 
} 

динамически добавлять в строку.

+2

'my @departments = map $ _, @ {$ opts -> {d}};' :) Нет, не используйте это, это странный способ сделать 'my @departments = @ {$ opts- > {d} // = []}; ' – ikegami

ответ

7

Выполнение этого:

my @departments = $opts->{'d'} ? @{$opts->{'d'}} : undef; 

такое же, как

my @departments = $opts->{'d'} ? @{$opts->{'d'}} : (undef); 

который, если $opts->{d} ложно назначит один элемент, undef, в массив @departments. Вам не нужен массив, содержащий один элемент. Вам нужен пустой массив.

Итак, что вы хотите сделать, это назначить пустой список @departments, например, так:

my @departments = $opts->{'d'} ? @{$opts->{'d'}} :(); 

одна вещь: Ваше название говорит «условно экземпляр нового массива Perl», и на самом деле то, что мы» повторное выполнение этого условно заполняет его. Он создается, когда вы говорите my @departments.

+0

Правильно, когда я говорю «условно экземпляр», я имею в виду воспроизводить следующее поведение: 'my @departments = @ {$ opts -> {'d'}}, если $ opts -> {'d'}' –

+0

@ s_dolan Использование 'my' с модификатором оператора [undefined behavior] (http://perldoc.perl.org/perlsyn.html#Statement-Modifiers) ... не делайте этого! «Значение переменной' my' может быть 'undef', любое ранее назначенное значение или, возможно, что-либо еще. Не полагайтесь на него. Будущие версии perl могут делать что-то отличное от версии perl, которую вы пытаетесь использовать Здесь будут драконы. – ThisSuitIsBlackNot

+0

@ThisSuitIsBlackNot Большое спасибо! С этого момента я не буду этого делать в своем коде. –

4

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

my @departments = $opts->{'d'} ? @{$opts->{'d'}} :(); 
+1

, если вы хотите избежать повторения:' map {$ _? @ $ _:()} $ opts -> {d} 'или' map @ $ _, grep $ _, $ opts -> {d} ' – ikegami

+0

Спасибо. Я не знаю, почему мне не пришло в голову использовать '()' вместо '@ {[]}'. – stevieb

+0

Ответ slimmed вниз определенно опрятен, но поскольку это в большой системе, где многие разработчики (и некоторые новые для Perl) будут копаться, я стараюсь держать ее более читаемой. Я также предлагаю использовать модуль [Английский] (http://search.cpan.org/~rjbs/perl-5.22.0/lib/English.pm), чтобы переименовать ваши '$ _' в' $ ARG'. –

2

Я хотел бы использовать

my @departments = @{ $opts->{d}||[] };

Если $ выбирает -> {d} не существует, это не соответствует действительности, таким образом, Perl выглядит для правой стороны '||' и находит пустой массив, который затем переводится в пустой список.

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

Рассмотрим альтернативный вариант:

$opts->{d} ||= []; 
my @departments = @{$opts->{d}}; 

Это будет первый набор пустой ссылкой на массив, затем отливали в виде массива, и будет в основном делать то же самое (если вы не хотели повторно бросить в массив, то этот метод позволит сэкономить вы неоднократно набираете || [].

Надеюсь, это поможет, я видел часто используемые мною обозначения для литья массивов/hashrefs (my %hash = %{ $hash||{} };), если не определено, было ли оно установлено.