前回の(1)はこちらから。
関数──Perl 6の特徴的文法
Perl 6には本当にたくさんの機能があります。ページは限られているので何を紹介すべきか迷いましたが、本稿では関数を取り上げます。
Perl 6の関数にはいくつかの種類があります。そして、それらにいろいろな機能が備わっています。
関数の種類
関数には、Sub、Block、WhateverCodeがあります。そしてそれらをまとめるCallableロールがあります。
Sub──普通の関数
普通の関数Subは、sub
キーワードで定義します。
Block──実行されうるもの
Blockである{}
を用いても、「実行されうるもの」を定義できます。
関数Subと、このBlockの違いはreturn
の扱いにあります。関数内でreturn
するともちろんその関数から復帰しますが、Block内でreturn
すると外側の関数から復帰しようとします。すなわち、
のreturn 2 * $_
はmap
に渡したBlockから復帰するのではなく、外側の関数even-array()
から復帰しようとします。この例では、おそらくそれは意図と違うでしょうから、
と書く必要があります。
WhateverCode──さらにカジュアルな実行されうるもの
WhateverCodeである*
によって、さらにカジュアルに「実行されうるもの」を定義できます。
Callable──関数をまとめるロール
ここまで紹介したSub、Block、WhateverCodeは、Callableロールのもとにまとまります。ロールとはほかの言語でのインタフェースに相当するもので、振る舞いを定義します。そしてSub、Block、WhateverCodeは、「実行されうる」という振る舞いを表すロールであるCallableを実装しているのです。
さて、実のところ任意のクラスをCallableロールを実装して定義すれば、それは「実行されうるもの」として扱えます。
クラスを用いれば、メンバー変数で状態を持った関数を作る、再利用可能な関数を作るなど、いろいろな可能性が出てきます。
引数、戻り値の宣言
すでにいくつかのコードに出てきましたが、Perl 6では関数を定義するときに引数を宣言できます。また、引数の型、戻り値の型も宣言できます。
この(Int $n, Str $s --> Callable)
のような関数の引数、戻り値の情報を、シグネチャと呼びます。
多重ディスパッチ
multiキーワードを使えば、同じ名前でシグネチャが異なる関数を複数定義し、それらを呼び分けられます。
この多重ディスパッチが特に威力を発揮するのはMAIN関数の場合です。
まず、MAIN関数について説明します。MAIN関数はプログラムが実行されると自動的に呼び出される関数で、コマンドライン引数からオプションをパースするという便利な機能が付いています。たとえば次のように定義すると、
以下に示すようにオプションを簡単に扱えます。
このMAIN関数は、多重ディスパッチを用いることでさらに便利になります。たとえば先ほど使ったモジュール管理ツールpandaには、次のようなMAIN関数が定義されています。
こうすることで、いわゆるサブコマンドによってMAIN関数を呼び分けられます。すなわちpanda install...
ならmulti MAIN('install', ...)
が呼ばれ、panda list ...
ならmulti MAIN('list', ...)
が呼ばれます。自分でサブコマンドによる分岐を書くより、プログラムがすっきりします。
関数のラップ
関数をラップして、その関数の前処理、後処理を付け加えることができます。
もしあるブロック内だけ関数をラップしたいのであれば、ブロックを抜けたときの処理を指定できるLEAVEとともに使うとよいでしょう。
Perl 6の関数には魅力的な機能がまだまだたくさんあります。詳しくは「Synopsis 6: Subroutines」を参照してください。
<続きの(3)はこちら。>
- 特集1
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現!
- 特集2
いまはじめるFlutter
iOS/Android両対応アプリを開発してみよう
- 特集3
作って学ぶWeb3
ブロックチェーン、スマートコントラクト、NFT