こんにちは、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) - ここで、「
Buf
doesBlob
」ということで、Buf
はBlob
roleをミックスインしています。「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日目の投稿でした。