スキップしてメイン コンテンツに移動

Perl 5 to 6 - クォートと構文解析

これはMoritz Lenz氏のWebサイトPerlgeek.deで公開されているブログ記事"Perl 5 to 6" Lesson 23 - Quoting and Parsingの日本語訳です。

原文はCreative Commons Attribution 3.0 Germanyに基づいて公開されています。

本エントリにはCreative Commons Attribution 3.0 Unportedを適用します。

Original text: Copyright© 2008-2010 Moritz Lenz

Japanese translation: Copyright© 2011 SATOH Koichi

NAME

"Perl 5 to 6" Lesson 23 - クォートと構文解析

SYNOPSIS

my @animals = <dog cat tiger>
# or
my @animals = qw/dog cat tiger/;
# or 

my $interface = q{eth0};
my $ips = q :s :x /ifconfig $interface/;

# -----------

sub if {
    warn "if() calls a sub\n";
}
if();

DESCRIPTION

クォート

Perl6には強力な文字列クォート機構があり、文字列のあらゆる機能を完全に制御できます。

Perl5にはシングルクォート、ダブルクォートそしてqw(...)(空白で分割するシングルクォート文字列リスト)があり、さらにq(...)qq(...)がそれぞれシングルクォートとダブルクォートの同義語になっていました。

一方のPerl6にはQというクォート演算子が定義されていて、様々な修飾子を取ります。 :b(バックスラッシュ)修飾子はバックスラッシュによる\nのようなエスケープシーケンスの展開を許し、:s修飾子はスカラ変数の展開を許し、:cはクロージャ("1 + 2 = { 1 + 2 }")の展開を許す、などなど。また:wqw/.../が行うように単語を分割します。

これらの修飾子は自由に組み合わせることができます。例えばスカラだけ展開し、他は展開しないqw/.../を作りたくはないでしょうか。まったく問題在りません:

my $stuff = "honey";
my @list = Q :w :s/milk toast $stuff with\tfunny\nescapes/;
say @list[*-1];                     # with\nfunny\nescapesと表示

利用できる修飾子のリストを示します。これはS02からほとんどそのまま盗んできました。 これらはすべて長い名前も持ちますが、ここでは省略します。

機能
    :q          \\と\q及び\'を展開する
    :b          その他の\nや\tのようなエスケープシーケンスも展開する
演算
    :x          シェルコマンドとして実行し、結果を返す
    :w          空白で分割する
    :ww         同上。クォートで囲まれた部分は分割しない
文字列展開
    :s          スカラを展開する     ($stuff)
    :a          配列を展開する       (@stuff[])
    :h          ハッシュを展開する   (%stuff{})
    :f          関数を展開する       (&stuff())
その他
    :c          クロージャを展開する ({code})
    :qq         :s、:a、:h、:f、:c、:bを展開する
    :regex      正規表現として解釈する

簡単のためにいくつか短い形式があります:

q       Q:q
qq      Q:qq
m       Q:regex

修飾子が短い形式の場合、:も省略して1語として書くことができます:

シンボル     元の形
qw          q:w
Qw          Q:w
qx          q:x
Qc          Q:c
# などなど

ただし、Perl5プログラマが見落としそうな動作しない形式が1つあります: Perl6では小カッコを使ってqw(...)と書くことはできません。これはサブルーチンqwの呼び出しとして解釈されます。

構文解析

これが構文解析の起点です: すべてのidentifier(...)という形式はサブルーチン呼び出しとして解釈されます。そう、全部です。

if($x<3)

はサブルーチンifの呼び出しと解釈されます。空白を使って曖昧性を解消できます:

if ($x < 3) { say '<3' }

あるいは単にカッコを取り去って:

if $x < 3 { say '<3' }

これはつまりPerl6にはキーワードがないということです。正確に言えばuseとかifのようなキーワードがありますが、これらは特別の構文の中で使われたときだけ特別扱いされます。

MOTIVATION

クォート修飾子の様々な組み合わせは既に内部的に使われています。例えば<...>を解析するq:wm/.../を解析する:regexです。 これらをユーザにも解放して柔軟性を向上させ、使いたいクォートの省略記法を提供するマクロを簡単に書けるようにすることは道理にかなっています。

またキーワードの特別性を制限することで、「キーワード」の定義を書き換えたい時に後方互換性の問題を大幅に減らすことができます。

SEE ALSO

http://perlcabal.org/syn/S02.html#Literals

コメント