はじめに

このページでは、perlスクリプトを利用して、perlスクリプトの中からサブルーチン実装を抽出する方法について説明します。

実現方法

論より証拠、ということで、まずは実証するサンプルコードをご覧ください。

サンプルコード(getSubroutineImplementation.pl)
my($aTargetFile)=$ARGV[0];

my(%tSubroutine)=();

open(DATA_FILE,'<'.$aTargetFile);
flock(DATA_FILE,1);
my(@tFileData)=<DATA_FILE>;
close(DATA_FILE);

my($tContent)=join('',@tFileData);

while($tContent=~ /(sub ([a-zA-z0-9_]{1,})\n\{\n(.|\n){1,}?\n\}\n)/g)
{
	$tSubroutine{$2}=$1;
}

foreach(sort keys %tSubroutine)
{
	my($tKey)=$_;
	my($tValue)=$tSubroutine{$tKey};

	print '# --------------------------------'."\n";
	print '# '.$tKey."\n\n";
	print $tValue."\n";
}
被抽出コード(sample.pl)
sub test1
{
	print 'subroutine test1 called!'."\n";
}

sub test2
{
	print 'subroutine test2 called!'."\n";
}

&test1();
&test2();
&test1();
&test2();

このサンプルコードで被抽出コードからサブルーチン実装を抽出してみます。
実行結果は以下の通りです。

実行結果
$ perl test.pl test.pl

# --------------------------------
# test1

sub test1
{
        print 'subroutine test1 called!'."\n";
}

# --------------------------------
# test2

sub test2
{
        print 'subroutine test2 called!'."\n";
}

このプログラムで一番重要なのは「while($tContent=~ /(sub ([a-zA-z0-9_]{1,})\n\{\n(.|\n){1,}?\n\}\n)/g)」の部分で、

sub hogehoge
{
    ........
}

のようなサブルーチン全体を抽出し、「hogehoge」のサブルーチン名をキーにして連想配列に格納します。

制限事項

上記のサンプルコードでは「sub」と「hogehoge」の間に複数のスペースやタブが入っていたり、「{」「}」が一行にひとつだけ記載されていない場合には、サブルーチン全体を上手く抽出することはできません。

もう少し正規表現部分を弄れば対応できると思いますので、トライしてみてください。

どんなことに使えるのか?

かなりの私は面倒臭がり屋なので、自分が作ったスクリプトでちょっとでも他のプログラムに転用できそうなものはサブルーチン化し、機能ごとに共通ライブラリとして保存しています。
この「共通ライブラリ」は結構便利なのですが、ちょっとしたシェルスクリプトを書くときに、使ってもいないサブルーチンが実装されたファイルをいちいちrequireするのはスクリプトの呼び出しのオーバーヘッド等もあり、あまり上手いやり方には思えません。

そうした時に、自分が書いたスクリプト内で使っているサブルーチンだけを共通ライブラリから切り出し、ひとつのファイルにまとめられたら便利ですよね。

上記のサンプルコードでは、「スクリプト内のサブルーチン名とサブルーチン実装を組にして抽出する」ことが出来ます。
こちらとあわせれば、利用しているサブルーチンのみ共通ライブラリから切り出すことが可能になりますので、是非ともお試しください。


あなたの探し物は見つかりましたか?
まさにこれだ
参考になった
ちょっと違う
これじゃない

何かメッセージがあればお願いします

このメッセージを非公開にする

ご注意

・頂いたメッセージは管理者のチェックの後、公開されます。
・メッセージの公開を希望されない場合には、「このメッセージを非公開にする」にチェックを入れてください。
・管理者が不適切と判断したメッセージは公開しませんので、予めご了承ください。


まだ評価がありません

表示できるメッセージはありません。