こんにちは、Perl 6 Advent Calendar 2016の23日目の投稿になります。
今回は、Inline::Perl5でPerl 5のAcme::Cakeを呼び出してケーキを焼きたいと思います。
イントロダクション
- Perl 6に入る前に、そもそもPerl 5でケーキを焼きたかったらどうすれば良かったでしょうか。ちょっとケーキを焼いてみましょう
cake.pl
use Acme::Cake;
print Acme::Cake->bake();
ケーキを焼く
$ perl cake.pl > cake.jpg
-
はい、これで焼けました。
cake.jpgの中身を確認してみましょう。(※ここでは画像は掲載しません) -
では、Perl 6で同じようなスクリプトを書いてみましょう
cake.p6
use Acme::Cake:from<Perl5>;
print Acme::Cake.bake;
- ケーキを焼いてみましょう
ケーキを焼く?
$ perl6 cake.p6 > cake.jpg
Cannot use a Buf as a string, but you called the Str method on it
in block <unit> at cake.p6 line 3
- あれ、うまく焼けませんね。では、どうやったらうまくケーキを焼けるでしょうか。
ケーキの焼き方
- 先に正解を言うと、
$*OUT.writeを使うとうまくケーキを焼くことができます
cake.p6
use Acme::Cake:from<Perl5>;
my $cake = Acme::Cake.bake;
$*OUT.write($cake);
ケーキを焼く
$ perl6 cake.p6 > cake.jpg
-
うまく焼けましたね。
cake.jpgの中身を確認してみましょう。(※ここでは画像は掲載しません) -
なぜうまく焼けたのでしょう。それを考えるために、下記のように
cake.p6を書き換えて$cakeの型を確認してみましょう。
cake.p6
use Acme::Cake:from<Perl5>;
my $cake = Acme::Cake.bake;
$cake.WHAT.say;
確認
$ perl6 cake.p6
(Buf)
- これで
$cakeはBufだと判明しました。(※1) - ここで、「
BufdoesBlob」ということで、BufはBlobroleをミックスインしています。「BlobはBinary Large OBject」の略です。 - つまり
$cakeというバイナリを書き込みたかったら、Blobを引数にとるwriteメソッドを使えばよいということがこれでわかるようになります。printは文字列を引数にとる(※2)のでこの場合不適です。
(※1) 気づいた方もいるかもしれませんが、実はイントロダクション内のエラーメッセージでもBufだと書いてあります
(※2) "文字列"という表現はいくらか不正確なので、きちんと知りたい方はドキュメントを読むのをすすめます。
参考
- https://docs.perl6.org/routine/write
- https://docs.perl6.org/type/Blob
- https://docs.perl6.org/type/Buf
- https://docs.perl6.org/routine/print
以上、Perl 6 Advent Calendar 2016の23日目の投稿でした。