2011-10-17 2 views
15

Там есть куча, поскольку Perl - довольно сладкий язык, но наиболее часто используемые операторы на любом языке представляют собой комбинацию операторов if и значений настроек. Я думаю, что нашел многих из них, но все еще есть несколько пробелов. В конечном счете, цель будет не писать имя переменной несколько раз:Какой синтаксический сахар доступен в Perl для уменьшения кода для операторов l/rvalue против операторов if?

Вот что я до сих пор:

$r ||= $s;   # $r = $s unless ($r); 
$r //= $s;   # $r = $s unless (defined $r); 
$r &&= $s;   # $r = $s if ($r); 
$r = $c ? $s : $t; # if ($c) { $r = $s } else { $r = $t } 
$c ? $r : $s = $t; # if ($c) { $r = $t } else { $s = $t } 
$r = $s || $t;  # if ($s) { $r = $s } else { $r = $t } 
$r = $s && $t;  # if ($s) { $r = $t } else { $r = $s = undef, 0, untrue, etc. } 
$c and return $r; # return $r if ($c); 
$c or return $r; # return $r unless ($c); 
$c and $r = $s;  # $r = $s if ($c); 
@$r{qw(a b c d)} # ($r->{a}, $r->{b}, $r->{c}, $r->{d}) 

Кто-то также был really interesting article на «секретный оператор», показанный здесь :

my @part = (
    'http://example.net/app', 
    ('admin' ) x!! $is_admin_link, 
    ($subsite) x!! defined $subsite, 
    $mode, 
    ($id  ) x!! defined $id, 
    ($submode) x!! defined $submode, 
); 

Однако то, что я нашел, чтобы отсутствовать в списке:

$r <= $s;     # read as "$r = min($r, $s);" except with short-circuiting 
$r = $s if (defined $s); # what's the opposite of //? 
$r and return $r   # can that be done without repeating $r? 

Есть ли еще что-то, что стоит добавить? Какие еще условные переменные набора доступны для сокращения кода? Что еще не хватает?

+0

'$ C && $ г = $ s' нужно немного больше сахара (вы должны сказать '($ r = $ s)') – mob

+0

@mob, боюсь, это довольно горький вкус для OP :-) – TMS

+0

'$ r =! $ s? $ s: $ t' - это то же самое, что '$ r = $ s && $ t' – mob

ответ

8

Эти структуры из вашего вопроса можно было бы написать немного более ясно используя низкий приоритет and и or ключевые слова:

$c and return $r; # return $r if ($c); 
$c or return $r;  # return $r unless ($c); 
$c and $r = $s;  # $r = $s if ($c); 

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

Другим полезным инструментом для синтаксического сахара является цикл for/foreach как локализатор на одно значение. Рассмотрим следующий пример:

$var = $new_value if defined $new_value; 

против

defined and $var = $_ for $new_value; 

или вещи, как:

$foo = "[$foo]"; 
$bar = "[$bar]"; 

$_ = "[$_]" for $foo, $bar; 

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

+0

О, я забыл про и/или слова. И да, я использую карту очень часто для таких определений, как 'my ($ id, $ name) = map {$ DEV -> {$ d} {$ _}} qw (hostid hostname);' –

+0

не забывайте фрагменты: 'my ($ id, $ name) = @ {$$ DEV {$ d}} {qw (hostid hostname)};' –

1

Один из самых больших объектов, требуемых для Perl, был switch statement. Это, наконец, появилось в Perl 5.10. Я просто использую пример из документации:

use feature qw(say switch); #My preference 
#use feature ":5.10";  #This does both "say" and "switch" 

[...] 

given($foo) { 
    when (undef) { 
     say '$foo is undefined'; 
    } 
    when ("foo") { 
     say '$foo is the string "foo"'; 
    } 
    when ([1,3,5,7,9]) { 
     say '$foo is an odd digit'; 
     continue; # Fall through 
    } 
    when ($_ < 100) { 
     say '$foo is numerically less than 100'; 
    } 
    when (\&complicated_check) { 
     say 'a complicated check for $foo is true'; 
    } 
    default { 
     die q(I don't know what to do with $foo); 
    } 
} 

Почему о»почему они идут с given/when и не switch/case, как вы найдете в большинстве языков является для меня загадкой. И почему, если в заявлении given/when, вы указываете его в use features как switch?

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

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

$r &&= $s; 

или

if ($r) { 
    $r = $s; 
} 

И, может быть, я мог бы понять, что я на самом деле имел в виду:

if (not defined $r) { 
    $r = $s; 
} 

И в этом случае, я мог бы даже сказать:

$r = $s if not defined $r; 

Хотя обычно мне не нравятся постфиксированные заявления, потому что люди, как правило, пропускают часть if, просматривая код.

Perl скомпилирован во время выполнения, а компилятор довольно эффективен. Таким образом, даже если это более прохладно, чтобы написать $r &&= $s, и он зарабатывает, он зарабатывает вам больше очков гика и меньше набирает, он не выполняется быстрее. Самое большое количество времени, затрачиваемого на код, - на его поддержание, поэтому я предпочел бы пропустить понравившиеся вещи и пойти на удобочитаемость.

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

${${${$employee_ref}[0]}{phone}}[0]; 

против

$employee_ref->[0]->{phone}->[0]; 

Конечно, если вы храните данные в виде ссылки на список на хэш в список, вы, вероятно, лучше с использованием объектно-ориентированного кодирования.

+0

Чтобы ответить на ваш вопрос об использовании функций, просто используйте «common :: sense»; Лучший из когда-либо изобретенных модулей! Что касается читаемости, то это доступно только для чтения, как человек, который может или не может его понять. Например, кто-то может не знать, что такое '$ a || die' действительно делает, но используется повсюду. Люди склонны уклоняться от оператора ~~ smart matching из-за этого, но все требуется, чтобы посмотреть ссылку. Это стоит усилий, чтобы сделать что-то так же просто, как '@q ~~ $ val', вместо того, чтобы беспокоиться о первом, или для цикла, или о чем-либо еще. –

+0

, если у вас есть такие имена, потому что они были перенесены с Perl 6. И в Perl 6 они были переименованы, потому что они делают намного больше, чем обычный переключатель/случай –

+0

Я не знаю о вас, но мне нравится думать о '$$ employee_ref [0 ] {phone} [0] ':) –

3

$r = $r < $s ? $r : $s;:

$r = $s if $r > $s; 

или

use List::Util qw(min); 

    $r = min($r, $s); 

или:

sub min_inplace { 
     my $min_ref = \shift; 
     for (@_) { $$min_ref = $_ if $$min_ref > $_; } 
    } 

    min_inplace($r, $s); 

$r = $s if (defined $s);:

$r = $s // $r; 

$r = $t; $r = $s if (defined $s);:

$r = $s // $t; 

$r = !$s ? $s : $t;:

$r = $s && $t; 
5

Там также левая часть Тройной оператор:

$cond ? $var1 : $var2 = "the value"; 

эквивалентно:

if ($cond) { 
    $var1 = "the value"; 
} else { 
    $var2 = "the value"; 
} 
+0

Это хороший вариант; Я добавлю. –

0

Там также:

$hash{$key||'foo'} = 1; # if($key) { $hash{$key} = 1 } else { $hash{'foo'} = 1 }