リリースされてそろそろ一年。
使ってみないとperl6のことがわからないので使ってみる。
まずは一番単純なcatコマンドのように動くコマンド作りから。
rakudo & panda インストール
rakudobrewというPerlBrewのようなスクリプトでインストール。簡単。
How to get Rakudo Perl 6 | rakudo.org
ドキュメントをインストール
そもそもperl6の書き方がわからない。
webで調べてもいいのですが、perldocを重宝していたので同じものが無いかと調べてみると p6doc というものがあったのでインストール。
$ panda install p6doc
自分の環境では libssl-dev の追加が必要だった。
また、p6docコマンドがPATHの通ったところに置かれなかったので調整した。
さらに、使っていると以下のコマンドの実行を勧められたので実行した。
$ p6doc-index build
cat.plからcat.p6へ
cat.pl
cat.plの挙動は以下を想定している。
$ cat helloworld
Hello
World
$ ./cat.pl helloworld
Hello
World
$ cat helloworld | ./cat.pl
Hello
World
実装は以下の通り。
#!/usr/bin/env perl
use strict;
use warnings;
while (<>) {
print;
}
cat.p6
先に結果を載せておく。
#!/usr/bin/env perl6
use strict;
for (lines) {
.say;
}
try & error
perl6で実行
cat.plをperl6で実行するよう書き換え。
#!/usr/bin/env perl6
use strict;
use warnings;
while (<>) {
print;
}
実行すると以下のエラーが出る。
$ ./cat.pl helloworld
===SORRY!===
Could not find warnings at line 4 in:
/home/ajishixo/.perl6
/home/ajishixo/.rakudobrew/moar-nom/install/share/perl6/site
/home/ajishixo/.rakudobrew/moar-nom/install/share/perl6/vendor
/home/ajishixo/.rakudobrew/moar-nom/install/share/perl6
CompUnit::Repository::AbsolutePath<189992464>
CompUnit::Repository::NQP<191589208>
CompUnit::Repository::Perl5<191589232>
warningsプラグマは無くなった様子。
use warnings を削る
#!/usr/bin/env perl6
use strict;
while (<>) {
print;
}
実行した結果
$ ./cat.pl helloworld
===SORRY!=== Error while compiling /home/ajishixo/dev/perl6/./cat.pl
Unsupported use of <>; in Perl 6 please use lines() to read input, ('') to represent a null string or () to represent an empty list
at /home/ajishixo/dev/perl6/./cat.pl:5
------> while (<⏏>) {
ダイアモンド演算子も無くなった様子。
ダイアモンド演算子をlinesに書き換え
#!/usr/bin/env perl6
use strict;
while (lines) {
print;
}
$ ./cat.pl helloworld
===SORRY!=== Error while compiling /home/ajishixo/dev/perl6/./cat.pl
Unsupported use of bare "print"; in Perl 6 please use .print if you meant $_, or use an explicit invocant or argument, or use &print to refer to the function as a noun
at /home/ajishixo/dev/perl6/./cat.pl:6
------> print⏏;
print;
はprint $_;
の$_
を省略した形でしたが、$_.print;
として$_
を省略し.print
という形になるのですね。
printを.printに書き換え
#!/usr/bin/env perl6
use strict;
while (lines) {
.print;
}
実行すると
$ ./cat.pl helloworld
Use of uninitialized value of type Any in string context.
Methods .^name, .perl, .gist, or .say can be used to stringify it to something meaningful.
in block <unit> at ./cat.pl line 6
Use of uninitialized value of type Any in string context.
Methods .^name, .perl, .gist, or .say can be used to stringify it to something meaningful.
in block <unit> at ./cat.pl line 6
stringのコンテキストでAny型の初期化されていない値が使われているとのこと。
Any型とはなんぞや、ということで先ほど入れたp6docに尋ねてみる。が、イマイチ分からず。。
.say
の使用をすすめられたので書き換える。
printをsayに書き換え
#!/usr/bin/env perl6
use strict;
while (lines) {
.say;
}
実行すると
$ ./cat.pl helloworld
(Any)
(Any)
またもAny。。
linesの戻り値が気になるのでp6docに尋ねてみる。
$ p6doc -f lines
We have multiple matches for 'lines'
Type::Cool.lines Type::Str.lines
Type::Supply.lines Type::IO::Handle.lines Type::IO::Socket::INET.lines
今回はファイルの読み込みなので Type::IO::Handle.lines を選ぶ。
$ p6doc -f Type::IO::Handle.lines
method lines
method lines($limit = Inf)
Return a lazy list of the file's lines read via get, limited to $limit
lines. The new line separator (i.e., $*IN.nl-in) will be excluded.
my @data;
my $data-file = open 'readings.csv';
for $data-file.lines -> $line {
@data.push($line.split(','))
}
分からん。
紆余曲折し、以下の記述にたどり着く。
$ p6doc variables
// 略
Calling a method on $_ can be shortened by leaving off the variable name:
.say; # same as $_.say
m/regex/ and /regex/ regex matches and s/regex/subst/ substitutions work on
$_:
say "Looking for strings with non-alphabetic characters...";
for <ab:c d$e fgh ij*> {
.say if m/<!alpha>/;
}
whileをforに書き換え
#!/usr/bin/env perl6
use strict;
for (lines) {
.say;
}
実行して無事成功。
$ ./cat.pl helloworld
Hello
World
$ cat helloworld | ./cat.pl
Hello
World
拡張子を変更
$ mv cat.pl cat.p6
おわりに
なぜwhileではダメでforなら良かったのかはp6doc control
を読んでみたけど分からず。
今後の使用で理解していこう。