关于 Perl 6 你要知道的 10 件事情

Ten Things You Need To Know about Perl 6

Jeffrey Goff, Evozon Systems LLC
OSCON London 2016
https://github.com/drforr
http://theperlfisher.blogspot.ro

资源

要闻

  • 干净, 一次性的可解析的文法
  • 对用户友好的错误信息
  • 友好的 Unicode
  • 对初学者有帮助的符号
  • Math that works
  • 函数签名
  • 用正则表达式引导
  • OO with a type lattice built on a Metaprogramming model
  • 自定义运算符
  • 内置并发

一次性文法

my @doctor = { :first('Christopher'), :last('Eccleston'), years => 1 },
             { :first('David'),       :last('Tennant'),   years => 4 },
             { :first('Matt'),        :last('Smith'),     years => 4 },
             { :first('Peter'),       :last('Capaldi'),   years => 3 };

say 'First New Who Doctor: ', @doctor[0]{'first'}, ' ', @doctor[0]<last>;

say "Average run: " ~ @doctor.elems R/ sum map { .<years> }, @doctor;

R/ 运算符会对调两边的表达式再进行计算。

my %hash := {  :name('Larry Wall'), :sex('male')  }; # {name => Larry Wall, sex => male}
say %hash{'name'}; #     Larry Wall
say %hash.<name>;  #     Larry Wall

访问散列的键值的另外一种语法是 %hash.<key>, 尖括号自动为 key 添加引号。

错误信息

sub mean( @a ) {
  my $sum = sum( @a )
  ( $sum / @a.elems )
}
say mean 1, 2, 4;
$ perl6 test.pl6

Two terms in a row across lines (missing semicolon or comma?)
at /home/jgoff/test.pl6:2
------>   my $sum = sum( @a )⏏<EOL>
    expecting any of:
        infix
        infix stopper
        postfix
        statement end
        statement modifier
        statement modifier loop

Unicode Friendly

my $α = 2 + ⅒  ; 

say $α ÷ 2;

# 1.05

Or, really old-school

use Slang::Roman;

say 0rↀ  + 0rDCLXVI;

# 1666

my $a = 0rIV / 0rM;

say $a;

# 0.004

This is really just a teaser to show off how powerful the internals really are.
The module itself is a bit too complex to show, but I like to think that the
fact that I can go in and muck about with the actual grammar, changing how
numbers are read and stored internally speaks volumes.

有意义的符号

my @powers = 1, 2, 4, 8;

my %foo = :name('Jeff'), :division('Programming');

say @powers[ 1, 2 ];

say %foo<name>;

# (2 4)

# Jeff

浮点数

$ perl -E 'say 0.1 + 0.2 - 0.3'

+5.55111512312578e-17

+$ ruby -e 'print 0.1 + 0.2 - 0.3'

+5.55111512312578e-17

+$ python -c 'print 0.1 + 0.2 - 0.3'

+5.55111512312578e-17

+$ perl6 -e 'say 0.1 + 0.2 - 0.3'

+0

+$ perl6 -e'say (0.1).nude'

+(1 10)

函数签名

sub plus( Int $a, Int $b ) {
    $a + $b
}

say plus 1, 2;

# 3

say plus 1, 2, 3;
===SORRY!=== Error while compiling -e
Calling a(Int, Int, Int) will never work with declared signature
(Int $a, Int $b)
at -e:1
------> ub foo( Int $a, Int $b ) { $a + $b }; say ⏏foo 1, 2, 3;

不那么正规的表达式

my $id = '[ { "first": "Christopher", "last": "Eccleston", "id": 1 } ]';

my regex Str     { '"' (<-[ " ]>+) '"' };
my regex Integer {         \d+         };

my regex Value {                       <Integer> | <Str>               };

my regex Pair  {             <Str> ':' \s+ <Value>                     };
my regex Pairs {     '{' \s+       <Pair>+    %% (',' \s+) \s+ '}'     };
my regex List  { '[' \s+           <Pairs>+   %% (',' \s+)     \s+ ']' };

$id ~~ m{ <List> };

say $/;

面向对象

enum Chirality <left right>;
enum Effort <minimum average maximum>;

class Hand {
    has Chirality $.chirality;
    has $.content; 
}

role Humanoid {
    has Hand $.left-hand  .= new( :chirality( left ) );
    has Hand $.right-hand .= new( :chirality( right ) );
}

class Character does Humanoid {
    has Str $.name is required;
    has Int @.Attr where 0 < * <= 18;

    method attack( Character $enemy, Effort $effort ) { ... } 
}

class Sword { has Int $.Dmg }

my $Wade = Character.new(:name('Wade'));
$Wade.left-hand.content = Sword.new( Dmg => 5 );
$Wade.right-hand.content = Sword.new( Dmg => 5 );

my $Francis = Character.new(:name('Francis'));

$Wade.attack($Francis,maximum);

看呐,合适的列表!

my $fh = open 'sample.tsv', :r;

my @line;
for $fh.lines -> $line {
    my ( $id, $last-name, $first-name ) =
        $line.chomp.split( "\t" );
    @line[$id - 1] = $last-name, $first-name;
}

close $fh;

say @line;

# [("Tyler", "Rose"), ("Smith", "Mickey"),
   ("Jones", "Martha"), ("Noble", "Donna")]

自定义运算符

multi sub prefix:<∑>( *@values ) {
    [+] @values
}

my $total = ∑ 0 ... ∞;
    
multi sub postfix:<⁺>( $x ) { $x.charge( +1 ) }
multi sub postfix:<⁻>( $x ) { $x.charge( -1 ) }
multi sub prefix:<√>( $x ) { sqrt( $x ) }

W⁺ = (-W¹ + iW²)/√2 ;
W⁻ = (-W¹ + iW²)/√2 ;

Perl 6 风格

for 'sample.txt'.IO.lines.kv -> $index, $line {
    my ( $method, $id, $name, timestamp ) = $line.chomp.split( "\t" );

    given $method {
        when 'create'   { %object{$id} = $name, $timestamp }
        when 'delete'   { %object{$id}:delete }
    }
    if $method eq 'read' | 'update' | 'delete' {
        say "missing object on line $index" unless %object{$id}
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 2009 有用的和有意思的循环 让我们来看一个基本的例子. 这是一个最简单清晰的语法的例子.在这并没有使用括号来包...
    焉知非鱼阅读 595评论 0 0
  • 公共类(框架) YTTabBarController
    写啥呢阅读 317评论 0 1
  • 低碳生活是对现代生活的优化,是节能环保的必然选择。 低碳生活重要在“低”上,所以减少碳排放量是十分必要的。在日常生...
    风_d23b阅读 407评论 0 0
  • 目 录 下一章 我的天呐,我发现了什么!就在十分钟前,我正好死不死一脸寡妇脸的瘫散在床上边翘着二郎腿抠脚,边用迷...
    一枚少年阅读 576评论 6 49