ランタイム関数
greple には、関数を指定することができるオプションがいくつもあります。プログラムから抜き出してみると、これだけありました。
--begin
,--end
,--prologue
,--epilogue
--callback
,--uniqsub
--block
,--inside
,--outside
,--include
,--exclude
--if
,--of
,--pf
--colormap
--le
ずいぶんとたくさんあります。中には --inside/outside
、--include/exclude
、--block
など、今までに説明してきたものも含まれています。今回は、これらのオプションで使われている関数の定義と利用方法について紹介します。
関数の使い方
ここで言う関数とは、Perl のサブルーチンのことです。greple は Perl で実装されていて、モジュールや初期設定ファイルの中に Perl のコードを記述することができます。そこで定義された関数をコマンド行から呼び出すことを可能にするのがこれらのオプションです。
関数の定義
関数は一般的に次のような形式で定義します。
sub hello {
my %arg = @_;
my $filename = delete $arg{&FILELABEL};
say "Hello $filename";
}
パラメータがある場合には配列 @_
に key-value 形式で渡されるので、連想配列 %arg
に代入すると、ラベルでアクセスできるようになります。FILELABEL
というラベルは特別で、ファイル名を渡すために使われます。扱うファイルが存在しない場合には、この項目はありません。ファイル名やパラメータを扱う必要がなければ、最初の2行は必要ないので、何もすることはありません。
関数の呼び出し
上で定義した関数は、コマンドラインから次のように呼び出すことができます。
greple --begin hello ...
ただ、関数名を指定するだけです。
パラメータを渡す場合は、次のように key
あるいは key=value
の形式で与えます。
greple --begin 'hello(debug,message=こんにちは,count=2)' ...
括弧が含まれていると、シェルの解釈を防ぐためにクォートしなければならないので、次のような呼び出し形式も可能です。
greple --begin hello=debug,message=こんにちは,count=2
パラメータに値が指定されていなければ 1 が渡されるので、この場合、関数 hello
には、
( "debug", 1, "message", "こんにちは", "count", "2" )
というリストが渡されます。
実行例
ファイルを処理する前に実行する関数を指定するオプション --begin
を例にとって実際に実行してみます。
上の関数を ~/.greplerc
内で定義しておくと、次のように使うことができます。最初に Hello sushi.txt
というメッセージが表示されています。
関数の定義をもう少し複雑にして、渡されたパラメータを使用するようにしてみましょう。
sub hello {
my %arg = ( message => "Hello", count => 1, @_ );
my $filename = delete $arg{&FILELABEL};
say "debug mode" if $arg{debug};
say "$arg{message} $filename" for 1 .. $arg{count};
}
パラメータを指定して実行すると、次のような結果になります。
データへのアクセス
関数が呼ばれる時、ファイルに含まれるデータ全体が、変数 $_
に保持されています。内容を参照するだけでなく、変数の値を変更すると、その結果に対して処理が行われます。
寿司メニューを処理する寿司
関数を定義してみます。
sub 寿司 {
my %arg = @_;
my $filename = delete $arg{&FILELABEL};
if ($arg{逆順}) {
$_ = join '', reverse /.*\n/g;
}
if ($arg{入れ替え}) {
use List::Util qw(shuffle);
my $寿司 = qr/(?<= )\S+/;
my @寿司 = shuffle /$寿司/g;
s/$寿司/pop @寿司/ge;
}
}
何もしなければこうです。
--begin 寿司=逆順
を指定するとこのようになります。
--begin 寿司=入れ替え
を指定するとこうなりました。まぐろづくしセットにまぐろが入ってません。困ります。
まとめ
--begin
オプションを例にとって、関数の定義と利用の仕方について紹介しました。このように、利用者やモジュールの開発者が作成した関数をコマンド行から自由に呼び出すことで、様々な機能を柔軟に利用することが可能になります。
このコマンドオプションと関数のインタフェースは、元々 greple を実装するために作られたものですが、その後 Getopt::EX
という独立したモジュールとして実装されていて、他の Perl スクリプトからも利用することができます。それに含まれる Getopt::EX::Long
は、広く使われている Getopt::Long
と互換性があるため、単にモジュール宣言を置き換えるだけで利用可能です。
SEE ALSO
- https://qiita.com/kaz-utashiro/items/5b6bcbe54891b3bd9db5
- https://qiita.com/kaz-utashiro/items/eb8c7067e6de34842fe3
- https://qiita.com/kaz-utashiro/items/165e744d4250adedc4c1
- https://qiita.com/kaz-utashiro/items/439e6abcecf36c520703
- https://qiita.com/kaz-utashiro/items/24ac0b8fdd30b598e069
- https://qiita.com/kaz-utashiro/items/a1ba4e3d07cf37dc25e3
- https://qiita.com/kaz-utashiro/items/0c8c944c17a72724b771
- https://qiita.com/kaz-utashiro/items/8783c2fd0cc4315b9a3d
- https://qiita.com/kaz-utashiro/items/84f5a6be6bf996076c64
- https://qiita.com/kaz-utashiro/items/ebc7ea99f800cfc8c90c
- https://qiita.com/kaz-utashiro/items/25a14e75380c39b5e0af
- https://qiita.com/kaz-utashiro/items/ebbeb8a5538a15ff04fc
- https://qiita.com/kaz-utashiro/items/b265deef9c9b1953a414
- https://qiita.com/kaz-utashiro/items/2b20e0226cffde213ce0
- https://qiita.com/kaz-utashiro/items/16b5142ef7a89aa35380
- https://qiita.com/kaz-utashiro/items/d19fe5ee859f31ce172c
- https://qiita.com/kaz-utashiro/items/09a5f5cf08ce314e2add ←イマココ
- https://qiita.com/kaz-utashiro/items/6e4b1f51455e587ef743
- https://qiita.com/kaz-utashiro/items/010f141f17e855aab4fc