2011-03-19: 複数行コメントについて加筆しました。
背景
Perlにもしあったらいいなぁと思う機能 - サンプルコードによるPerl入門を読んでて「それPerl6でできるよ」と思ったので。一応Perlです。一応。
1. ダブルクォーテーションの中で関数が展開できる機能
ダブルクォート(qq
演算子)はエスケープシーケンス、スカラ、配列、ハッシュ、関数、クロージャを展開します:
"aaa { $book.title } bbb"
Q
クォート演算子でオレオレ展開ルールも作れます(Rakudoだとまだ動きませんが):
Q:function/funcall: &func()/;
Q:closure/closure: { ucfirst('hello') ~ ', world' }/;
# qq//と同じ
Q:qq/$scalar, @array[], %hash{}, &subroutine(), { 'closure' }/;
2. メソッドにおけるオブジェクトの名前
自身をself
で参照できます:
class Foo {
has Str $.objective = 'world';
method greet {
say "Hello, { self.objective }";
}
}
Foo.new.greet; # Hello, world
Foo.new(:objective<Perl6>).greet; # Hello, Perl6
3. データを簡単にダンプする標準関数
オブジェクトをPerl6コードにダンプする.perl
メソッドがあります:
say 42.perl; # 42
say { foo => 'bar', hoge => qw/fuga piyo/ }.perl; # {"foo" => "bar", "hoge" => ("fuga", "piyo")}
デバッグ用には変数名が分かり易いようにペア記法を組み合わせて、note
で標準エラー出力に書き出します(warn
は例外を投げるので注意):
my $obj = Foo.new(:objective<Perl6>);
note :$obj.perl; # "obj" => Foo.new(objective => "Perl6")
4. ファイルの内容を一度に読み込むモジュール
slurp
が組み込み関数(と組み込みオブジェクトのメソッド)です。ファイルオープンに失敗すると例外を投げます:
open('filename').slurp;
slurp 'filename';
でもこれってPerl5でもFile::Slurp
とか色々ある気がする。
5. Mojo::Base程度の小さなクラスビルダー
最初からまともなOO機能が付いてきます:
class Vector2D {
has Num $.x = 0;
has Num $.y = 0;
method squared_norm() { [+] ($.x, $.y).map: (* ** 2) }
method norm() { self.squared_norm.sqrt }
}
class Vector3D is Vector2D {
has Num $.z = 0;
method squared_norm() { [+] ($.x, $.y, $.z).map: (* ** 2) }
}
multi sub prefix:<~>(Vector3D $v --> Str) { "<{ $v.x }, { $v.y }, { $v.z }>" }
multi sub infix:<->(Vector3D $v, Vector3D $u --> Vector3D) {
my ($x, $y, $z) = ($v.x, $v.y, $v.z) Z- ($u.x, $u.y, $u.z);
Vector3D.new(:$x, :$y, :$z);
}
my $v = Vector3D.new(:x(1), :y(3.sqrt));
my $u = Vector3D.new(:x(1), :z(1));
my $delta = $v - $u;
say "{ ~$v } norm: { $v.norm }"; # <1, 1.73205080756888, 0> norm: 2
say "{ ~$u } norm: { $u.norm }"; # <1, 0, 1> norm: 1.4142135623731
say "{ ~$delta } norm: { $delta.norm }"; # <0, 1.73205080756888, -1> norm: 2
6. Net::FTPのコマンドが失敗したときは自動的に例外を投げてほしい
好みの問題なのでパス。サブクラス作ってオーバーライドするのがセオリーでしょうか。
7. ハッシュスライスと配列スライスのための関数
リファレンスはAutovivifyされるので必要ありません:
my %hash = foo => 'hoge', bar => qw/hoge fuga/, baz => 'piyopiyo';
my $hash_ref = %hash;
my @slice = $hash_ref<foo bar>; # ('hoge', ('hoge', 'fuga'))
8. Perlの最新の機能とstrictとwarningsとutf8とautodieをレキシカルに有効にするプラグマ
strict
/warnings
/autodie
相当はデフォルト。Unicode関連はまだ策定中のようですが、Rakudoだと文字列はUTF-8です。
9. 複数行コメント
これはPerl6でもPODで書くことになっています(S02)。=begin comment
と=end comment
で囲むか、=for comment
で空行までをコメントにします。
POD処理系は知らない(あるいはコメントだと知っている)フォーマットの内容は出力しないので、ドキュメントと混ざるとかそういう心配はありません。
ちなみに=cut
は必要なくなりました(というか、なくなりました)。
もう1つ、埋め込みコメント(Embedded comment)という範囲を指定したコメントも利用できます。#`
に続けて好きな区切り子を使って囲みます(ただし#
は駄目):
say 'hello, ' ~ #`( コメントは空白扱いなので文中に出現しても構わない ) 'world';
$obj\ #`( 空白が許されない場所ではUnspaceで取り除く必要がある ).method;
#`{{
複数行コメントの例。カッコは重ね打ちもできる。
この場合数と種類が対応した閉じカッコが出現するまでがコメントとして扱われる。
} まだ閉じない。
} ここもまだコメントの中。
}} # ここで閉じられる
#`/* Cっぽくしたいならこう書ける(*は単なるコメントの一部) */
#`「Unicodeでカッコとして定義された文字なら何でも使える。誰得」
埋め込みコメントの区切り子の扱いはQ
クォート演算子と同じです。
蛇足ですが2つめの例で$obj\ #`( ... )`.say
とあるのはPerl6がオペランドと後置演算子(ここではメソッド呼び出しの.
)の間に空白の出現を許していないためで、バックスラッシュは余分な空白を取り除くためのものです。
この機能はUnspaceと呼ばれています。Cプリプロセッサやシェルで行末に置くバックスラッシュを他の空白やコメントにも一般化したものと思えば大体合ってます。
コメント
コメントを投稿