Capにblock, inject, extends文を実装した

336, 2020-07-01

目次

Capに新機能を追加した

Capというシェル型のスニペットマネージャーを作っています。
このCapにはテンプレート言語が実装されています。
今回はこのテンプレート言語の新機能3つを紹介したいと思います。

新機能3つ↓

  • extendsキーワード
  • block文
  • inject文

extendsキーワード

extendsキーワードは関数と一緒に使います。
これは関数に他の関数を継承させるキーワードです。
たとえばf1という関数があって、f2という関数にf1を継承させたい場合は下のようにします。

{@
    def f1():
    end

    def f2() extends f1:
    end
@}

これで関数f2は関数f1を継承できました。
関数f2から親の関数、つまりf1を呼びたいときはsuperを使います。

{@
    def f2() extends f1:
        super()
    end
@}

これらの機能はこれから紹介するblock文とinject文で必要な機能です。

block文

関数内の処理は「ブロック」という単位で区切ることが出来ます。
ブロックを区切るにはblock文を使います。

{@
    def f1():
        block contents:
        end
    end
@}

↑の場合、contentsという識別子のブロックが関数内に作成されます。
このブロックは複数作ることが出来ます。

{@
    def f1():
        block header:
        end

        block contents:
        end

        block footer:
        end
    end
@}

ブロックは、関数をテンプレートとして使いたい時に、その構成を記述するのに使われます。
↑の場合はheader, contents, footerという3つのブロックを作っているので、ここに外から別の処理を流し込むことが出来るようになります。
別の処理を流し込むにはinject文を使います。

inject文

inject文はblock文で区切られたブロック内に、別の処理を注入するのに使われます。
例えば↓のような関数f1があったとして、

{@
    def f1():
        block contents:
            puts(1)
        end
    end
@}

関数f1内のブロックcontentsに別の処理を流し込みたい場合は、まず関数f1を継承した関数を定義します。

{@
    def f2() extends f1:
    end
@}

それからinject文で親のcontentsブロックに別の処理を注入します。

{@
    def f2() extends f1:
        inject contents:
            puts(2)
        end
    end
@}

これで関数f2から関数f1contentsブロックに、puts(2)という処理を注入できました。
あとはf2内でsuperを呼びます。

{@
    def f2() extends f1:
        inject contents:
            puts(2)
        end
        super()
    end
@}

これで関数f2から関数f1が実行されます。
あとはスコープの一番外で関数f2を呼び出します。

{@
    f2()
@}

これの出力結果は「2」になります。

これらの機能の使いみち

フレームワークやテンプレート言語を使っている人はピンと来たと思いますが、これらはテンプレート言語の基本的な機能と言えます。
たとえばベースとなるHTMLを作っておき、そのHTMLの部分的なブロックに別のHTMLを注入したいときなどに、これらの新機能は使うことが出来ます。
例えば↓のようにです。

{@
    def base():
        puts("header")
        block contents:
        end
        puts("footer")
    end

    def index() extends base:
        inject contents:
            puts("contents")
        end
        super()
    end

    index()
@}

イメージとしては雛形に外部から鉛(HTML)を流し込み、新しい部品を作るという感じですね。
実装期間としては4日ぐらいでだいたい実装できました。思ったより時間がかかりました。

おわりに

CapはMITライセンスで公開されているので良かったら使ってみてください(^^)



姉妹ブログを見に行く。

投稿者名です。64字以内で入力してください。

必要な場合はEメールアドレスを入力してください(全体に公開されます)。

投稿する内容です。

スポンサーリンク

スポンサーリンク

スポンサーリンク

スポンサーリンク