perl6をインストールした後cat.plをcat.p6に書き換える
リリースされてそろそろ一年。
使ってみないと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を読んでみたけど分からず。
今後の使用で理解していこう。