Perlでパッケージ名つきの関数を動的に呼び出す方法

Perlでパッケージ名つきの関数を動的に呼び出す方法

Posted at May 14,2014 1:23 AM
Tag:[Perl]

Perlでパッケージ名つきの関数を動的に呼び出す方法を紹介します。

1.はじめに

仕事で、パッケージ名つきの関数を動的に呼び出す必要が生じました。

パッケージ名のつかない関数を動的に呼び出す方法や、オブジェクトとして呼び出す方法はネットで結構ヒットするのですが、パッケージ名つきの関数を呼び出し方が分かりません。

ということで、本エントリーでパッケージ名つきの関数を動的に呼び出す方法を備忘録でまとめておきます。

条件によって違うかもしれませんがベストプラクティスや認識誤りがあればどこかでつぶやいてください。

2.パッケージ名つきの関数を動的に呼び出す

パッケージ名つきの関数を動的に呼び出すコードは以下です。

ここではパッケージ、メソッド、引数をすべて動的(=呼び出し元のパラメータを使うという意味)に生成します。

#!/usr/bin/perl
 
use strict;
use warnings;
 
sub test {
    my ( $class, $method, $param ) = @_;
 
    eval "require $class;";
    if ( $@ ) {
        print "Error: " . $@;
        exit;
    }
 
    my $func= "${class}::${method}(". '$param' . ")";
    my $result = eval "$func;";
    if ( $@ ) {
        print "Error: " . $@;
        exit;
    }
    print $result;
}
 
my $data;
$data->{value} = 'Hello World!';
test( 'Sample', 'foo', $data );

モジュールは以下です。

package Sample;
 
use strict;
use warnings;
 
sub foo {
    my $param = shift;
    print $param->{value};
    return 1;
}
 
1;

以下、コードの解説です。

パッケージの呼び出しはevalコマンドで行います。

    eval "require $class;";

パッケージが存在しない場合、$@(evalによるPerlの構文エラーメッセージ)のチェックでNGになります。

    if ( $@ ) {
        print "Error: " . $@;
        exit;
    }

たとえば次のような感じです。

Error: Can't locate Sample2.pm in @INC (@INC contains: C:/usr/site/lib C:/usr/lib .) at (eval 1) line 1.

パッケージ、メソッドとパラメータを文字列結合してメソッド呼び出しのフォーマットを生成します。パラメータはevalで評価されるよう、シングルクォーテーションで括ります。

    my $func= "${class}::${method}(". '$param' . ")";

evalで「Sample::foo($param)」を起動します。起動メソッドの返却値も受け取ることができます。

    my $result = eval "$func;";

指定したメソッドがみつからないなどの場合、2回目の$@のチェックでNGになります。

    if ( $@ ) {
        print "Error: " . $@;
        exit;
    }

たとえば次のような感じです。

Error: Undefined subroutine &Sample::foo2 called at (eval 2) line 1.

上記のサンプルを実行すると次のような出力を得られます(改行は入りません)。

Hello World!
1

4.参考サイト

参考サイトは以下です。ありがとうございました。

Perl での動的関数呼び出し
関連記事
zenback
人気エントリー
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)