Perl的一些优雅功能或用途是什么?

Rob*_*t P 35 perl

什么?Perl漂亮吗? 优雅?他一定是在开玩笑!

这是真的,那里有一些丑陋的Perl.有些人,我的意思是很多.我们都看过了.

嗯,这是象征汤.不是吗?

是的,有符号.就像'数学'有'符号'一样.只是我们程序员更熟悉标准的数学符号.我们开始接受母语中的符号,无论是ASM,C还是Pascal.Perl刚决定再多做一些.

好吧,我认为我们应该摆脱所有不必要的符号.使代码看起来更好.

这样做的语言已经存在.它被称为Lisp. (很快,perl 6.)

好的,聪明的家伙.事实是,我已经可以发明自己的符号了.它们被称为功能和方法.此外,我们不想重塑APL.

哦,假冒的另一个自我,你真好笑!这是真的,Perl可以很漂亮.它也可能非常丑陋.使用Perl,TIMTOWTDI.

那么,你最喜欢的Perl代码是什么?

cha*_*aos 28

Perl有助于使用列表/哈希来实现命名参数,我认为这些参数非常优雅,并且对自记录代码有很大的帮助.

my $result = $obj->method(
    flux_capacitance       => 23,
    general_state          => 'confusion',
    attitude_flags         => ATTITUDE_PLEASANT | ATTITUDE_HELPFUL,
);
Run Code Online (Sandbox Code Playgroud)


pjf*_*pjf 24

我最喜欢的优雅Perl代码不一定非常优雅.它们是优雅的,让你摆脱许多Perl开发人员已经陷入的所有坏习惯.我需要花费数小时或数天的时间来展示他们应得的细节,但作为一个简短的清单,他们包括:

如果你懒得跟踪链接,我最近在Linux.conf.au上就上述大部分内容进行了讨论.如果你错过了,那就有一个在线视频(ogg theora).如果你懒得观看视频,我今年作为OSCON的教程做了一个大大扩展的演讲版本(题为正确的做Perl).

祝一切顺利,

保罗


Mar*_*las 19

我很惊讶没有人提到Schwartzian变换.

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

在没有闷闷的操作员的情况下,

my $file = do { local $/; readline $fh };
Run Code Online (Sandbox Code Playgroud)

  • 这实际上被称为`decorate-sort-undecorate`,起源于Lisp. (3认同)
  • 它只修复了perl sort没有可以缓存的键函数这一事实,只是一个比较函数.Python的新关键参数就是这样做的.ST无论如何都是美丽的,但是来自其他语言的人只会认为Perl排序因为需要这种奇怪的咒语而被打破. (2认同)

Chr*_*utz 16

有一个用户希望您的程序处理的文件列表?不想意外处理程序,文件夹或不存在的文件?试试这个:

@files = grep { -T } @files;
Run Code Online (Sandbox Code Playgroud)

而且,就像魔术一样,你已经淘汰了所有不合适的条目.不想无声地忽略它们?在最后一行之前添加此行:

warn "Not a file: $_" foreach grep { !-T } @files;
Run Code Online (Sandbox Code Playgroud)

为每个无法处理标准错误的文件打印一条很好的警告消息.没有使用的相同的东西grep将是这样的:

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

grep(和map)可以用来使代码更短,同时仍然保持其可读性.


Cha*_*ens 11

"或死"构造:

open my $fh, "<", $filename
    or die "could not open $filename: $!";
Run Code Online (Sandbox Code Playgroud)

使用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";
    }
}
Run Code Online (Sandbox Code Playgroud)

用于分解重复代码的匿名子例程:

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

$body->();
$body->() while $continue;
Run Code Online (Sandbox Code Playgroud)

代替

#some amount of work
while ($continue) {
    #some amount of work again
}
Run Code Online (Sandbox Code Playgroud)

基于散列的调度表:

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

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

代替

while (my $name = iterator()) {
    if ($name eq "foo") {
        foo();
    } elsif ($name eq "bar") {
        bar();
    } elsif ($name eq "baz") {
        baz();
    } else {
        die "$name not implemented";
    }
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*t P 9

我最喜欢的一个例子是Perl实现的阶乘计算器.在Perl 5中,它看起来像这样:

use List::Util qw/reduce/;
sub factorial {
    reduce { $a * $b } 1 .. $_[0];
}
Run Code Online (Sandbox Code Playgroud)

如果数字<= 1或者字符串,则返回false;如果传入数字则返回数字(如果是分数则向下舍入).

期待Perl 6,它看起来像这样:

sub factorial {
    [*] 1..$^x
}
Run Code Online (Sandbox Code Playgroud)

而且(从上面的链接中的博客)你甚至可以实现这个作为运营商:

sub postfix:<!>(Int $x) {
    [*] 1..($x || 1)
}
Run Code Online (Sandbox Code Playgroud)

然后在你的代码中使用它,如下所示:

my $fact5 = 5!;
Run Code Online (Sandbox Code Playgroud)


bru*_*nov 9

带有构造函数,getter/setter和类型验证的三行类:

{
    package Point;
    use Moose;

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

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

$point->x(25);
Run Code Online (Sandbox Code Playgroud)

  • Moose真的让Perl成为理想的OOP平台(恕我直言). (2认同)

Rob*_*t P 7

如果你有一个逗号分隔的标志列表,并想要一个查找表,你所要做的就是:

my %lookup = map { $_ => 1 } split /,/, $flags;
Run Code Online (Sandbox Code Playgroud)

现在您可以简单地测试您需要哪些标志,如下所示:

if ( $lookup{FLAG} ) {
    print "Ayup, got that flag!";
}
Run Code Online (Sandbox Code Playgroud)


Ali*_*har 6

我很惊讶没人提到这一点.这是我认为的杰作:

#!/usr/bin/perl
                                           $==$';
                                         $;||$.| $|;$_
             ='*$ (                  ^@(%_+&~~;# ~~/.~~
         ;_);;.);;#)               ;~~~~;_,.~~,.* +,./|~
    ~;_);@-,  .;.); ~             ~,./@@-__);@-);~~,.*+,.
  /|);;;~~@-~~~~;.~~,.           /.);;.,./@~~@-;.;#~~@-;;
  ;;,.*+,./.);;#;./@,./        |~~~~;#-(@-__@-__&$#%^';$__
   ='`'&'&';$___="````"  |"$[`$["|'`%",';$~=("$___$__-$[``$__"|
              "$___"|       ("$___$__-$[.%")).("'`"|"'$["|"'#").
        '/.*?&([^&]*)&.*/$'.++$=.("/``"|"/$[`"|"/#'").(";`/[\\`\\`$__]//`;"
        |";$[/[\\$[\\`$__]//`;"|";#/[\\\$\\.$__]//'").'@:=("@-","/.",
       "~~",";#",";;",";.",",.",");","()","*+","__","-(","/@",".%","/|",
        ";_");@:{@:}=$%..$#:;'.('`'|"$["|'#')."/(..)(..)/".("```"|"``$["|
        '#("').'(($:{$'.$=.'}<<'.(++$=+$=).')|($:{$'.$=.'}))/'.("```;"|
        "``$[;"|"%'#;").("````'$__"|"%$[``"|"%&!,").${$[};`$~$__>&$=`;$_=
       '*$(^@(%_+&@-__~~;#~~@-;.;;,.(),./.,./|,.-();;#~~@-);;;,.;_~~@-,./.,
        ./@,./@~~@-);;;,.(),.;.~~@-,.,.,.;_,./@,.-();;#~~@-,.;_,./|~~@-,.
          ,.);););@-@-__~~;#~~@-,.,.,.;_);~~~~@-);;;,.(),.*+);;# ~~@-,
           ./|,.*+,.,.);;;);*+~~@-,.*+,.;;,.;.,./.~~@-,.,.,.;_)   ;~~~
             ~@-,.;;,.;.,./@,./.);*+,.;.,.;;@-__~~;#~~@-,.;;,.*   +);;
               #);@-,./@,./.);*+~~@-~~.%~~.%~~@-;;__,. /.);;#@-   __@-
                 __   ~~;;);/@;#.%;#/.;#-(@-__~~;;;.;_ ;#.%~~~~  ;;()
                      ,.;.,./@,.  /@,.;_~~@- ););,.;_   );~~,./  @,.
                      ;;;./@,./|  ~~~~;#-(@- __,.,.,.    ;_);~~~ ~@
                       -~~());;   #);@-,./@,  .*+);;;     ~~@-~~
                       );~~);~~  *+~~@-);-(   ~~@-@-_      _~~@-
                       ~~@-);;   #,./@,.;.,    .;.);@      -~~@-;
                       #/.;#-(   ~~@-@-__      ~~@-~~       @-);@
                       -);~~,    .*+,./       |);;;~        ~@-~~
                        ;;;.;     _~~@-@     -__);.         %;#-(
                        @-__@      -__~~;#  ~~@-;;          ;#,.
                        ;_,..         %);@-,./@,            .*+,
                        ..%,           .;.,./|)             ;;;)
                        ;;#~            ~@-,.*+,.           ,.~~
                       @-);            *+,.;_);;.~         ~););
                      ~~,.;         .~~@-);~~,.;.,         ./.,.;
                      ;,.*+        ,./|,.);  ~~@-         );;;,.(
                    ),.*+);                              ;#~~/|@-
                  __~~;#~~                                $';$;;