Каковы некоторые изящные функции или использование Perl?

Если observableOne может иметь только одну подписку, вы можете сделать это несколькими способами. Самый простой способ - ввести Subject; он будет подписан на observableOne, а все остальные подписчики подпишутся на тему:

PublishSubject<DataType> observableOneStream = PublishSubject.create();

observableOne
  .subscribe( observableOneStream );
...
observableOneStream.subscribe( firstSubscription );
...
observableOneStream.subscribe( secondSubscription );
35
задан 13 revs, 5 users 59% 23 May 2017 в 12:25
поделиться

13 ответов

Perl упрощает использование списков/хешей для реализации названный параметрами, которые я считаю очень изящными и огромная помощь самодокументированию кода.

my $result = $obj->method(
    flux_capacitance       => 23,
    general_state          => 'confusion',
    attitude_flags         => ATTITUDE_PLEASANT | ATTITUDE_HELPFUL,
);
28
ответ дан chaos 27 November 2019 в 06:28
поделиться

Мои любимые части изящного кода Perl не обязательно изящны вообще. Они метаизящны и позволяют Вам избавляться от всех тех дурных привычек, в которые проскользнули многие разработчики Perl. Мне потребовались бы часы или дни, чтобы показать им всем в деталях, которых они заслуживают, но как короткий список они включают:

, Если Вы слишком ленивы, чтобы перейти по ссылкам, я недавно сделал разговор в Linux.conf.au о большей части вышеупомянутого. Если Вы пропустили его, существует видео его онлайн (ogg theora). Если Вы слишком ленивы для просмотра видео, я делаю, значительно расширенная версия разговора как учебное руководство в OSCON в этом году (дал право делающее право Perl ).

Всего самого лучшего,

Paul

24
ответ дан 2 revs 27 November 2019 в 06:28
поделиться

Классы с тремя линиями с конструкторами, методом get/методами set и вводят проверку:

{
    package Point;
    use Moose;

    has ['x', 'y'] => (isa => 'Num', is => 'rw');
}

package main;
my $point = Point->new( x => '8', y => '9' );

$point->x(25);
9
ответ дан 2 revs 27 November 2019 в 06:28
поделиться

Я абсолютно любовь Черный Perl (связываются с версией, переписанной для компиляции под Perl 5). Это компилирует, но насколько я могу сказать, что это ничего на самом деле не делает.

Это - то, что Вы получаете для языка, записанного лингвистом из прагматической перспективы, а не с теоретической точки зрения.

Хождение дальше, от которого, можно думать о Perl, что люди жалуются на как Perl гибридного языка (совершенно полезный, но не выразительный, и остерегаются попытки выразить что-либо сложное в нем), и материал, что @pjf говорит почти как "надлежащий" Perl, язык Shakespeare, Hemingway, Hume и так далее. [редактирование: допустите ошибку, хотя легче для чтения, чем Hume и менее датированный, чем Shakespeare.] [переиздают и надо надеяться менее алкогольный, чем Hemingway]

3
ответ дан 3 revs, 2 users 83% 27 November 2019 в 06:28
поделиться

Более бедные машинистки как я, которые заболели судорогами, поражающими клавишу Shift слишком часто, и имеют почти безрассудный страх использования точки с запятой, начали писать наш код Perl в python отформатированные файлы.:)

, например,

>>> k = 5
>>> reduce(lambda i,j: i*j, range(1,k+1),1)
120
>>> k = 0
>>> reduce(lambda i,j: i*j, range(1,k+1),1)
1
-17
ответ дан popcnt 27 November 2019 в 06:28
поделиться

Я удивлен, что никто не упомянул, что Schwartzian Преобразовывают.

my @sorted =
  map  { $_->[0] }
  sort { $a->[1] <=> $b->[1] }
  map  { [ $_, expensive_func($_) ] }
@elements;

И в отсутствие хлебать оператора,

my $file = do { local $/; readline $fh };
19
ответ дан 2 revs, 2 users 89% 27 November 2019 в 06:28
поделиться

Имеет список файлов пользователя, хочет, чтобы Ваша программа обработала? Не хотите случайно обрабатывать программу, папку или несуществующий файл? Попробуйте это:

@files = grep { -T } @files;

И, как волшебство, Вы избавились от всех несоответствующих записей. Не хотите игнорировать их тихо? Добавьте эту строку перед последней:

warn "Not a file: $_" foreach grep { !-T } @files;

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

my @good;
foreach(@files) {
  if(-T) {
    push @good, $_;
  } else {
    warn "Not a file: $_";
  }
}

grepmap) может использоваться для создания кода короче, все еще сохраняя это очень читаемым.

16
ответ дан Chris Lutz 27 November 2019 в 06:28
поделиться

"Или умирают" конструкция:

open my $fh, "<", $filename
    or die "could not open $filename: $!";

Использование qr//для создания грамматик:

#!/usr/local/ActivePerl-5.10/bin/perl

use strict;
use warnings;
use feature ':5.10';

my $non_zero         = qr{[1-9]};
my $zero             = qr{0};
my $decimal          = qr{[.]};
my $digit            = qr{$non_zero+ | $zero}x;
my $non_zero_natural = qr{$non_zero+ $digit*}x;
my $natural          = qr{$non_zero_natural | $zero}x;
my $integer          = qr{-? $non_zero_natural | $zero}x;
my $real             = qr{$integer (?: $decimal $digit)?}x;

my %number_types = (
    natural => qr/^$natural$/,
    integer => qr/^$integer$/,
    real    => qr/^$real$/
);

for my $n (0, 3.14, -5, 300, "4ever", "-0", "1.2.3") {
    my @types = grep { $n =~ $number_types{$_} } keys %number_types;
    if (@types) {
        say "$n is of type", @types == 1 ? " ": "s ", "@types";
    } else {
        say "$n is not a number";
    }
}

Анонимные подпрограммы раньше факторизовали дублирующий код:

my $body = sub {
    #some amount of work
};

$body->();
$body->() while $continue;

вместо

#some amount of work
while ($continue) {
    #some amount of work again
}

Основанные на хеше таблицы отправки:

my %dispatch = (
    foo => \&foo,
    bar => \&bar,
    baz => \&baz
);

while (my $name = iterator()) {
    die "$name not implemented" unless exists $dispatch{$name};
    $dispatch{$name}->();
}

вместо

while (my $name = iterator()) {
    if ($name eq "foo") {
        foo();
    } elsif ($name eq "bar") {
        bar();
    } elsif ($name eq "baz") {
        baz();
    } else {
        die "$name not implemented";
    }
}
11
ответ дан chaos 27 November 2019 в 06:28
поделиться

Любимым моим примером является реализация Perl факториального калькулятора. В Perl 5 это похоже так:

use List::Util qw/reduce/;
sub factorial {
    reduce { $a * $b } 1 .. $_[0];
}

Это возвращает false, если число <= 1 или строка и число, если число передается в (округление в меньшую сторону если часть).

И с нетерпением ожидая Perl 6, это похоже на это:

sub factorial {
    [*] 1..$^x
}

И также (из блога в ссылке выше) можно даже реализовать это как оператор:

sub postfix:<!>(Int $x) {
    [*] 1..($x || 1)
}

и затем используйте его в своем коде как так:

my $fact5 = 5!;
9
ответ дан 4 revs, 3 users 91% 27 November 2019 в 06:28
поделиться

Если Вы имеете список разделенных запятой значений флагов и хотите справочную таблицу для них, все, что необходимо сделать:

my %lookup = map { $_ => 1 } split /,/, $flags;

Теперь можно просто протестировать, для которых флагов Вам нужно как так:

if ( $lookup{FLAG} ) {
    print "Ayup, got that flag!";
}
7
ответ дан 2 revs, 2 users 94% 27 November 2019 в 06:28
поделиться

Я удивлен, что никто не упомянул это. Это - шедевр, по-моему:

#!/usr/bin/perl
                                           $==$';
                                         $;||$.| $|;$_
             ='*$ (                  ^@(%_+&~~;# ~~/.~~
         ;_);;.);;#)               ;~~~~;_,.~~,.* +,./|~
    ~;_);@-,  .;.); ~             ~,./@@-__);@-);~~,.*+,.
  /|);;;~~@-~~~~;.~~,.           /.);;.,./@~~@-;.;#~~@-;;
  ;;,.*+,./.);;#;./@,./        |~~~~;#-(@-__@-__&$#%^';$__
   ='`'&'&';$___="````"  |"$[`$["|'`%",';$~=("$___$__-$[``$__"|
              "$___"|       ("$___$__-$[.%")).("'`"|"'$["|"'#").
        '/.*?&([^&]*)&.*/$'.++$=.("/``"|"/$[`"|"/#'").(";`/[\\`\\`$__]//`;"
        |";$[/[\\$[\\`$__]//`;"|";#/[\\\$\\.$__]//'").'@:=("@-","/.",
       "~~",";#",";;",";.",",.",");","()","*+","__","-(","/@",".%","/|",
        ";_");@:{@:}=$%..$#:;'.('`'|"$["|'#')."/(..)(..)/".("```"|"``$["|
        '#("').'(($:{$'.$=.'}<<'.(++$=+$=).')|($:{$'.$=.'}))/'.("```;"|
        "``$[;"|"%'#;").("````'$__"|"%$[``"|"%&!,").${$[};`$~$__>&$=`;$_=
       '*$(^@(%_+&@-__~~;#~~@-;.;;,.(),./.,./|,.-();;#~~@-);;;,.;_~~@-,./.,
        ./@,./@~~@-);;;,.(),.;.~~@-,.,.,.;_,./@,.-();;#~~@-,.;_,./|~~@-,.
          ,.);););@-@-__~~;#~~@-,.,.,.;_);~~~~@-);;;,.(),.*+);;# ~~@-,
           ./|,.*+,.,.);;;);*+~~@-,.*+,.;;,.;.,./.~~@-,.,.,.;_)   ;~~~
             ~@-,.;;,.;.,./@,./.);*+,.;.,.;;@-__~~;#~~@-,.;;,.*   +);;
               #);@-,./@,./.);*+~~@-~~.%~~.%~~@-;;__,. /.);;#@-   __@-
                 __   ~~;;);/@;#.%;#/.;#-(@-__~~;;;.;_ ;#.%~~~~  ;;()
                      ,.;.,./@,.  /@,.;_~~@- ););,.;_   );~~,./  @,.
                      ;;;./@,./|  ~~~~;#-(@- __,.,.,.    ;_);~~~ ~@
                       -~~());;   #);@-,./@,  .*+);;;     ~~@-~~
                       );~~);~~  *+~~@-);-(   ~~@-@-_      _~~@-
                       ~~@-);;   #,./@,.;.,    .;.);@      -~~@-;
                       #/.;#-(   ~~@-@-__      ~~@-~~       @-);@
                       -);~~,    .*+,./       |);;;~        ~@-~~
                        ;;;.;     _~~@-@     -__);.         %;#-(
                        @-__@      -__~~;#  ~~@-;;          ;#,.
                        ;_,..         %);@-,./@,            .*+,
                        ..%,           .;.,./|)             ;;;)
                        ;;#~            ~@-,.*+,.           ,.~~
                       @-);            *+,.;_);;.~         ~););
                      ~~,.;         .~~@-);~~,.;.,         ./.,.;
                      ;,.*+        ,./|,.);  ~~@-         );;;,.(
                    ),.*+);                              ;#~~/|@-
                  __~~;#~~                                $';$;;
6
ответ дан 2 revs, 2 users 98% 27 November 2019 в 06:28
поделиться

Добавление к любви к map и grep, мы можем записать простой синтаксический анализатор командной строки.

my %opts = map { $_ => 1 } grep { /^-/ } @ARGV;

Если мы хотим, мы можем установить каждый флаг на, он - индекс в @ARGV:

my %opts = map { $ARGV[$_] => $_ } grep { $ARGV[$_] =~ /^-/ } 0 .. $#ARGV;

Тот путь, если флаг имеет аргумент, мы можем получить аргумент как это:

if( defined( $opts{-e} ) ) {
  my $arg = $ARGV[ $opts{-e} ];
  # do -e stuff for $arg
}

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

Если Вам не нравится, какой длины некоторые из тех строк, можно ли всегда использовать промежуточные переменные или просто удобные разрывы строки (эй, фанатики Python? Вы слышите это? Мы можем поместить одну строку кода через две строки, и она все еще работает!), чтобы заставить его выглядеть лучше:

my %opts = map  { $ARGV[$_] => $_   }
           grep { $ARGV[$_] =~ /^-/ } 0 .. $#ARGV;
2
ответ дан 2 revs 27 November 2019 в 06:28
поделиться

Этот механизм анализа файлов компактен и прост в настройке (пропускать пустые строки, пропускать строки, начинающиеся с X, и т. д.).

open(H_CONFIG, "< $file_name") or die("Error opening file: $file_name! ($!)");
while (<H_CONFIG>)
{
   chomp;         # remove the trailing newline
   next if $_ =~ /^\s*$/; # skip lines that are blank
   next if $_ =~ /^\s*#/; # skip lines starting with comments
   # do something with the line
}

Я использую этот тип конструкции в различных ситуациях сборки - где мне нужно либо предварительно, либо постобработать файлы полезной нагрузки (S-записи и т. д.) или C-файлы или собрать информацию о каталоге для ' умная сборка ».

1
ответ дан 27 November 2019 в 06:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: