Top/マニュアル/文法/6.文字列内埋め込み要素の展開
  トップページへ   [ 一覧 | 検索 | 最終更新 ]   [ 差分 | 履歴 | 凍結 ]

文字列内埋め込み要素の展開

文字列の中に変数や関数を埋め込んで、これらの実行結果を当該位置へ挿入することができます。

範囲付き展開

要素を%( )で囲んで埋め込みます。

request
{
    _i = "pen"
    "This is a %(_i)."
}

requestを実行すると、"This is a pen."が出力されます。 %( )はいわゆるeval(文字列をスクリプトコードと解釈して実行する)のような動作を行います。 単一の関数や変数だけでなく、数式を埋め込むことができます。

request
{
    "1+2+3は%(1+2+3)です。"
}

requestは"1+2+3は6です。"を出力します。

文の文字列は内部にダブルクォートを含むことが出来ない点に注意してください。したがって、文字列を含む数式を埋め込むことは出来ません。以下はエラーです。

request
{
    "This is a %(_i = "pen")."
}

このような場合は、埋め込みを使用せず通常の数式として結合します。

request
{
    "This is a " + (_i = "pen") + "."
}

ブラケット( )による演算順序制御は範囲付き展開でも同様に働きます。~以下の例を見てください。

request
{
    "遊星「%(_i = planet)」は遠い。この遊星は%(color(_i))色をしている。"
}

planet
{
    "mars"
    "saturn"
    "pluto"
}

color
{
    case _argv[0] {
    when "mars";   "red"
    when "saturn"; "yerrow"
    when "pluto";  "blue"
    others;        "unknown"
    }
}

最も( )が深いのはcolor(_i)の引数ですので、_i = planetの前にcolorが呼び出されてしまいます。
ブラケットを過剰付与して演算順序を調整してください。

"遊星「%((_i = planet))」は遠い。この遊星は%(color(_i))色をしている。"

これで矛盾の無い文字列が得られるようになります。

範囲付き展開は辞書の読み込み時に静的に解析されるため、後から マニュアル/関数/DICLOAD などで定義した関数を認識できません。
どうしてもそのような使い方をしたい場合は、 マニュアル/関数/EVAL の利用を検討してください。

名称最長一致展開

( )を付与せず、単に%のみでも埋め込み展開は機能します。

request
{
   o      = "pen"
   obj    = "eraser"
   object = "world"
   "This is a %object."
}

obje
{
    "television"
}

展開対象は%以降の文字列に一致する最も長い名前を持った変数/関数となります。上の例の場合、もっともよく一致するのは変数objectですから、これが採用されます。
結果は"This is a world."となります。

変数は刻々と作成されたり消えたりしますから、展開対象が状況によって変化することになります。
これは範囲付き展開には見られない特徴です。

request
{
   val   = "red"
   trans
   --
   value = "blue"
   trans
}

trans
{
    "%value"
}

transは二度実行されますが、最初と二度目では"%value"の動きが変わります。すなわち、最初は変数val+"ue"、二度目は変数valueと解釈されます。
requestの出力は"redueblue"です。

%[ ]という書式で過去の展開結果を再利用できます。

request
{
    "「%planet」は遠い。「%city」も遠い。もっとも%[1]になら行けなくもない。"
}

planet
{
    "mars"
    "saturn"
    "pluto"
}

city
{
    "newyork"
    "moscow"
    "madrid"
}

%[i]は0オリジンでi番目の展開結果を得ます。
つまり上の例では、%[0]が%planetの、%[1]が%cityの展開結果を示しています。

%[ ]は範囲付き展開では使えません。範囲付き展開で過去の結果を再利用したい場合は、それを変数へ入れてください。

名称最長一致による展開は実行する度に展開対象を検索しなおしますので、範囲付き展開と比べて動作速度が劇的に遅いです。
本当に必要な場合は別ですが、通常は範囲付き展開を利用すべきでしょう。