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
を読んでみたけど分からず。
今後の使用で理解していこう。