Wait the light to fall

Learn Raku From Roast

焉知非鱼

Learn Raku From Roast

Raku 的 Roast 仓库是一个测试套件, 我们可以从这个仓库中学习到很多 Raku 的知识。

元运算符 #

  • cross
dd <a b> X <c d>
# Output: (("a", "c"), ("a", "d"), ("b", "c"), ("b", "d")).Seq


dd 1 X 1 X 1 X 1
# Output: ((1, 1, 1, 1),).Seq


dd 1, 2, 3 X** 2, 4
# Output: 1, 1, 4, 16, 9, 81).Seq


my @result = gather {
    for 1..3 X 'a'..'b' -> ($n, $a) {
        take "$n|$a"
    }
}

dd @result;
# Output: Array @result = ["1|a", "1|b", "2|a", "2|b", "3|a", "3|b"]


my @result = gather for (1..3 X 'A'..'B') -> $na {
    take $na.join(':');
}

dd @result;
# Output: Array @result = ["1:A", "1:B", "2:A", "2:B", "3:A", "3:B"]


dd <a b> X, <c d>;
# Output: (("a", "c"), ("a", "d"), ("b", "c"), ("b", "d")).Seq


dd <a b> X~ <1 2>;
# Output: ("a1", "a2", "b1", "b2").Seq


dd <a b> X, 1,2 X, <x y>;
# Output: (("a", 1, "x"), ("a", 1, "y"), ("a", 2, "x"), ("a", 2, "y"), ("b", 1, "x"), ("b", 1, "y"), ("b", 2, "x"), ("b", 2, "y")).Seq


dd 1,2 X* 3,4;
# Output: (3, 4, 6, 8).Seq


dd 1,2 Xcmp 3,2,0;
# Output: (Order::Less, Order::Less, Order::More, Order::Less, Order::Same, Order::More).Seq


dd 1 X* 3,4;
# Output: (3, 4).Seq


dd 1, 2 X* 3;
# Output: (3, 6).Seq


dd 1 X* 3;
# Output: (3,).Seq


# $[] does not flatten
dd $[1,2] X~ <a b>
# Output: ("1 2a", "1 2b").Seq
  • zip
dd <a b> Z <c d>;
# Output: (("a", "c"), ("b", "d")).Seq


dd 1, 2, 3 Z** 2, 4;
# Output: (1, 16).Seq


dd <a b> Z~ <1 2>;
# Output: ("a1", "b2").Seq


dd 1,2 Z* 3,4;
# Output: (3, 8).Seq


dd 1,2 Zcmp 3,2,0;
# Output: (Order::Less, Order::Same).Seq


dd (1..* Z** 1..*).[^5];
# Output: (1, 4, 27, 256, 3125)


dd (1..* Z+ (3, 2 ... *)).[^5];
# Output: (4, 4, 4, 4, 4)


dd 1 Z* 3,4;
# Output: (3,).Seq


dd 1, 2 Z* 3;
# Output: (3,).Seq


dd 1 Z* 3;
# Output: (3,).Seq


dd <a b c d> Z 'x', 'z', *;
# Output: (("a", "x"), ("b", "z"), ("c", "z"), ("d", "z")).Seq


dd 1, 2, 3, * Z 10, 20, 30, 40, 50;
# Output: ((1, 10), (2, 20), (3, 30), (3, 40), (3, 50)).Seq


dd (2, 10, * Z 3, 4, 5, *).[^5];
# Output: ((2, 3), (10, 4), (10, 5), (10, 5), (10, 5))


dd <a b c d> Z~ 'x', 'z', *;
# Output: ("ax", "bz", "cz", "dz").Seq


dd 1, 2, 3, * Z+ 10, 20, 30, 40, 50;
# Output: (11, 22, 33, 43, 53).Seq


dd (2, 10, * Z* 3, 4, 5, *).[^5];
# Output: (6, 40, 50, 50, 50)


dd [Z](1,2,3;4,5,6;7,8,9);
# Output: ((1, 4, 7), (2, 5, 8), (3, 6, 9)).Seq


dd [Z<](1,2,3;4,5,6;7,8,9);
(Bool::True, Bool::True, Bool::True).Seq
  • hyper
my $a      := (1,2,3);
my $b      := (2,4,6);


# 以下表达式都输出  (3, 6, 9)

dd $a >>+<< $b;
dd $a  »+«  $b;
dd $a >>+>> $b;
dd $a  »+»  $b;
dd $a <<+>> $b;
dd $a  «+»  $b;
dd $a <<+<< $b;
dd $a  «+«  $b;

dd $a >>[&infix:<+>]<< $b;
dd $a  »[&infix:<+>  $b;
dd $a >>[&infix:<+>]>> $b;
dd $a  »[&infix:<+>  $b;
dd $a <<[&infix:<+>]>> $b;
dd $a  «[&infix:<+>  $b;
dd $a <<[&infix:<+>]<< $b;
dd $a  «[&infix:<+>  $b;

»*« 运算符的优先级比 »+« 运算符的优先级高:

dd (1, 2, 3) »+« (10, 20, 30) »*« (2, 3, 4);
# Output: (21, 62, 123)

unary postfix(一元后缀运算符)

my @r = (1, 2, 3);
@r»++;
dd @r;
# Output: Array @r = [2, 3, 4]

unary prefix(一元前缀运算符)

my @r;
@r =  (3, 2, 1);
dd @r;
# Output: Array @r = [-3, -2, -1]

dimension upgrade(升维), auto dimension upgrade on rhs/lhs ASCII notation

my @r = (1, 2, 3) >>+>> 1;
dd @r;
# Output: Array @r = [2, 3, 4]


my @r = 2 <<*<< (10, 20, 30);
dd @r;
# Output: Array @r = [20, 40, 60]

both-dwim and non-dwim sanity:

dd (1,2,3) <<~>> <A B C D E>;
# Output: ("1A", "2B", "3C", "1D", "2E")

extension(扩展)

dd (1,2,3,4) >>~>> <A B C D E>;
# Output: ("1A", "2B", "3C", "4D")


dd (1,2,3,4,5) <<~<< <A B C D>;
# Output: ("1A", "2B", "3C", "4D")


dd (1,2,3,4) >>~>> <A B C>;
# Output: ("1A", "2B", "3C", "4A")


dd (1,2,3) <<~<< <A B C D>;
# Output: ("1A", "2B", "3C", "1D")


dd (1,2,3,4) >>~>> <A B>;
# Output: ("1A", "2B", "3A", "4B")


dd (1,2) <<~<< <A B C D>;
# Output: ("1A", "2B", "1C", "2D")


dd (1,2,3,4) >>~>> <A>;
# Output: ("1A", "2A", "3A", "4A")


dd (1,) <<~<< <A B C D>;
# Output: ("1A", "1B", "1C", "1D")


dd (1,2,3,4) >>~>> 'A';
# Output: ("1A", "2A", "3A", "4A")


dd 1 <<~<< <A B C D>;
# Output: ("1A", "1B", "1C", "1D")

枚举 #

  • 匿名枚举

匿名枚举返回一个 Map:

my $e = enum < ook! ook. ook? >; # Map.new((ook! => 0, ook. => 1, ook? => 2))
say $e.keys.elems; #  3
say $e<ook!>;      #  0
say $e<ook.>;      #  1
say $e<ook?>;      #  2 
say so $e ~~ Map;  #  True
say $e.keys;       #  (ook? ook! ook.)

anon enum <un> 等价于 enum :: <un>:

anon enum <un>; #  Map.new((un => 0))
say +un;        #  0

my %e = enum :: < foo bar baz >; #  {bar => 1, baz => 2, foo => 0}
say %e<bar>; #  1
say baz;     #  baz
say +baz;    #  2
  • 枚举作为角色

枚举可以用在 butdoes 中, 用以命令一个想要的属性:

enum Maybe <No Yes Dunno>;
class Bar { }

class Foo does Maybe {}
my $x = Foo.new(Maybe => No);

say $x.No;    # True
say $x.Yes;   # False
say $x.Dunno; # False

my $y = Bar.new() does Maybe(Yes);
say $y.Yes;   # True
say $y.No;    # False
say $y.Dunno; # False


my $z = Bar.new() but Maybe(Dunno);
say $z.No;
say $z.Yes;
say $z.Dunno;

属性 #

  • 代理

官方文档关于 handles 的介绍很粗糙, 看完依然不知道怎么使用。