perl6 のワンライナー


20160105

正月休みに、触ってみたものの、、、

取り敢えずメモったの。

##### バージョン
```
$ perl6 -v 
This is Rakudo version 2015.12 built on MoarVM version 2015.12
implementing Perl 6.c.
```

## コマンドラインスイッチ

[ここ](https://design.perl6.org/S19.html#Backward_(In)compatibility)

- `-i` が消えたのはちょっと残念
- `-l` はデフォルトの挙動になったので削除されている。

### -a

実装予定はある様だが、今の所は実装されてない（？）。

`.split` を使えとの事だが、 `.words` っつーのもある。

### -0

外した理由は、[ここ](https://design.perl6.org/S19.html#Removed_Syntactic_Features)。

これ外して欲しくないなあ。ごく稀にしか使わんかったけど。

## 特殊変数
### @*ARGS

旧 `@ARGV`

```
$ perl6 -e '.say for @*ARGS' 1 2 3 4 5 
1
2
3
4
5
$ perl6 -e '@*ARGS.say' 1 2 3 4 5
[ 1 2 3 4 5 ]
$ perl6 -e '@*ARGS[2].say' 1 2 3 4 5
3
```

配列の要素へのアクセスが、 `$arr[0]` じゃない事に留意。

### $*ARGFILES

ワンライナーでのファイルハンドルは、 `$*ARGFILES`

```
$ perl6 -ne '.say if $*ARGFILES.eof' SOMETHING.txt
```

- `$*ARGFILES.filename` で、`perl5` の `$ARGV`
- `$*ARGFILES.ins` で、`perl5` の `$.`
- `$*ARGFILES.eof` で、`perl5` の `eof()`
	- `eof` の挙動ではなく `eof()` なので注意

`.eof` が `eof()` の挙動しかないのだったら、ワンライナー使いにはちょっと厳しい、、、


### $

`$.` が廃止。

その代りに、登場した anonymous な変数

```
$ perl6 -ne 'say ++$ ~ ": $_"' SOMETHING.txt
```

- `~` で連結

一見、`$*ARGFILES.ins` よりも短かくなって、良さげだが、lexical scope 毎に別制御


```
$ perl6 -ne '++$; say $' SOMETHING.txt
(Any)
(Any)
(Any)
$ perl6 -ne 'state $a; $a =  ++$ ； say $a' SOMETHING.txt
1
2
3
```

`$a =  ++$` な事するくらいだったら、普通に `++$a` する。

使い方によっては強力だろう。

## 演算子
### Flipflop operator.

perl5 の range operator のスカラーコンテキストでの挙動が、切り離された。
[ここ](http://doc.perl6.org/language/operators#infix_ff)の `ff` がらみの所。

定番の FASTA 切り出し。
perl5 では、[こんな感じ](http://qiita.com/bunzaemon/items/efcb3f20329bc68bb8bc#%E7%AF%84%E5%9B%B2%E6%BC%94%E7%AE%97%E5%AD%90)。

```perl:perl6
$ perl6 -ne '.say if /\>gi\|blah/ fff^ /\>/' MULTIFASTA
```

以前の `.` が `f` に代り、`...` が `fff` に。
で、`^` で含まず指定。

- `E0` 判定せずに済むので、その分かなり楽っちゃー楽。
- `>` がメタ文字になっちゃったのでエスケープが必要。
- `$.` が廃止。つーことで、暗黙の行番号範囲指定も出来なくなった。


### range operator

range operator は更に二つの別物から構成されてるっぽい。

- infix ..
- infix ...

適当にコードを実行したものをメモ

```
$ perl6 -e 'say 1..4'
1..4
$ perl6 -e 'say 1...4'
(1 2 3 4)
```
この時点で、返すものが違う

```
$ perl6 -e 'say 2 ~~ 1..4' 
True
$ perl6 -e 'say 2 ~~ 1...4'
(False True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True ...)
```
スマートマッチでも挙動が違う。

```
$ perl6 -e 'say 4..1'
4..1
$ perl6 -e 'my @a = 4..1 ; say @a'
[]
$ perl6 -e 'say 4...1'
(4 3 2 1)
```

逆順range は、 `...` の方だけ。

```
$ perl6 -e 'my @a = 1 ^..^ 4 ; say @a'
[2 3]
$ perl6 -e 'my @a = 1 ...^ 4 ; say @a
[1 2 3]
```

含まず指定は、 `...` では末尾のみ。

```
$ perl6 -e 'say 1 .. 4 Z~ 1 .. 4'
(11 22 33 44)
$ perl6 -e 'say  ( 1 ... 4 ) Z~ (1 ... 4 )'
(11 22 33 44)
```

zip するのに括弧なりが必要。

#### おおっ

```
$ perl6 -e '.say for q{01} .. 12 '
01
02
03
04
05
06
07
08
09
10
11
12
```

#### おお、、、orz...

```
$ perl6 -e '.say for 12 ... q{01} ' | head -10
12
13
14
15
16
17
18
19
20
21
```


### 三項演算子

```
条件 ?? 真の時の値 !! 偽の時の値
```

```
$ perl6 -ne 'say  /a/ ?? $_ !! q{no}' SOMETHING.txt
```


### Reduction operators

```
$ perl6 -e '( [+] @*ARGS).say' 1 2 3 4 5
15
$ perl6 -e '( [~] @*ARGS).say' 1 2 3 4 5
12345
```
[] の中に演算子

## 他

### BEGIN, END

```
$ perl6 -ne 'BEGIN { 42.say ; };  END { 42.say ; };  .say ' SOMETHING.txt
```

`BEGIN`, `END` ブロックはそれぞれ健在

- 但し、ブロックの後にセミコロン必須
- キーワード（`BEGIN` とか）の後にスペース必須

### sort

```
$ perl6 -e '@*ARGS.sort({ $^a <=> $^b }).say' 10 9 3 1 2
(1 2 3 9 10)
$ perl6 -e '@*ARGS.sort({ $^a.chars, $^a}).say' 10 9 3 1 2 
(1 2 3 9 10)
```

- デフォでは文字列ソート
- `$a`, `$b` の代りは、 `$^a`, `$^b` つか、 `$^` がキモで後は、`[a-z]`
- `$^a.chars` はタイプ数が増えるだけだから、覚える必要無いか？


### reverse/complement

```
$ perl6 -e 'q{ACACTTTGC}.trans("ACGT" => "TGCA").flip.say' 
GCAAAGTGT
```
- `tr///` が `.trans` に。
- `scalar` の `reverse` は、 `.flip` に。

```
$ perl6 -e 'q{ACACTTTGC}.trans("ACGT" => "TGCA").reverse.say' 
(TGTGAAACG)
```


`list` の `reverse` は、また別で、意図せずコードが動きやがるところが、どーにも。

### 50base 区切り
実行速度とか検討の余地あるが、 `perl5` のバージョンをそのまま移したら。

```
$ perl6 -e 'my $a = q{A} x 98 ; $a ~~ s:g/(.**1..50)/$0\n/ ; $a.print' 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
```

- `(.{1,50})` は、`(.**1..50)` に。
- `$1`　は、 `$0` に。
- `/g` 修飾子は、 `:g/` の形に。


### 先読み言明

```
$ perl6 -e 'my $a = qq{>A\n} ~ q{a} x 20 ~ qq{\n} ; $a ~= $a  ; $a ~~ s:g/<before \>A >/\n/ ; $a.say '

>A
aaaaaaaaaaaaaaaaaaaa

>A
aaaaaaaaaaaaaaaaaaaa

```

- `(?=>)` が、 `<before \> >` に。
	- 文字クラス（？）利用の `<?[>]>` の方が、見た目はすっきりする。

言明については、[ここ](http://doc.perl6.org/language/5to6-nutshell#Special_matchers_generally_fall_under_the_%3C%3E_syntax)。


### ハイパー演算子

**バージョンによって挙動が違うかも**

http://doc.perl6.org/language/operators#Hyper_Operators

```
@a <<OP<< @b
```

`OP` には、演算子。

積算とかさせるのに便利かなーっと思ったので。

```
$ cat test.txt
1	2	3
4	5	6
7	8	9
$ perl6 -e 'my @a = (0,0,0) ;  @a <<+=<< .words for @*ARGS[0].IO.lines ; say @a ' test.txt
[12 15 18]
```

この例では、 @a の各要素に、 `+=` で積算してる。

素直に、

```
$ perl6 -ne 'state @a =(0,0,0); @a <<+=<< .words; say @a if $*ARGFILES.eof' test.txt
``` 

こう書きたいのに、`state` がまともに機能してくれません。`scope` の仕様だろうけど、変更は無いのだろうか。

`use vars` に該当するモジュールは、無いわけだし、、、

>Discouraged in Perl 5. See http://perldoc.perl.org/vars.html.
>You should refactor your Perl 5 code to remove the need for use vars, before translating into Perl 6.
>[引用元](http://doc.perl6.org/language/5to6-nutshell#vars)

#### 普通に動かせば state が機能する

```
$ perl6 -e 'for q{test.txt}.IO.lines { state @a = (0,0,0) ; @a <<+=<< .words ; say @a  }'
[1 2 3]
[5 7 9]
[12 15 18]
```

#### 感覚的にちょっと

拡張する、って言うんだから、`+=` の時も拡張して欲しい。

```
$ perl6 -e 'my @a = ( 0 ) ; my @b = (1,2,3) ; @a <<+=<< @b ; @a.say'
[6]
$ perl6 -e 'my @a = ( 0 ) ; my @b = (1,2,3) ; @a = @a <<+<< @b ; @a.say'
[1 2 3]
```