Perlでプラガブルモジュールを作ろう!

第2回 attributeを使ってplugin作成を支援する

この記事を読むのに必要な時間:およそ 5 分

メソッドを生やす?

Gopperにメソッドを追加する為に肝心な事は,Gopperに生やしたいメソッドにはMethodというattributeを指定しなければなりません。Methodを指定されたメソッドは,そのメソッド名でGopperからcallする事が出来ます。

厳密にいうとメソッドが生えるわけではなく$gooper->call('config_dump')というcallメソッドから呼び出せるようになります。ただし Class::Component::Component::Autocall::* といったcomponentを利用する事により,本当にメソッドが生えるようになります。

package Foo;
use strict;
use warnings;
use base 'Class::Component::Plugin';
__PACKAGE__->load_components(qw/ Autocall::InjectMethod /);
1;

といったコードを書く事により,Method attributeで追加したメソッドを本当に生やす事が出来ます。

追加したモジュールを利用可能にする

ただpluginを書いただけではGopperに影響を与える事は出来ません。そこで追加したpluginを利用するコードを書く必要があります。

何をするかと言うと,追加したpluginをロードして追加されたメソッドを呼び出す処理を書きます。今回はgopper.plに対して処理を追加して行きます。

まずはpluginのロードです。

use lib file( $FindBin::RealBin, 'lib' )->stringify;
use Gopper;
Gopper->load_plugins(qw/ Method::ConfigDump /);

load_pluginsメソッドによってpluginをロードします。Method::ConfigDumpとしか書かれていませんが,Gopper::Pluginは自動補完されます。

次は追加したメソッドの呼び出しです。gopper.plのstartサブルーチンを書き換えます。

sub start {
    my $gopper = Gopper->new(config => shift);
    $gopper->call('config_dump');
    $gopper->run;
}

callメソッドで,追加されたconfig_dumpメソッドを呼び出します。Class::Component::Component::Autocall::InjectMethodなどを使用している時には,$gopper->config_dump;と簡潔に書けます。

実行してみよう!

追加したコードを実際に動かしてみましょう。gopper.plを動かすにはYAMLで記述されたPlaggerのような設定ファイルが必要です。

#config.yaml
global:
  log:
    level: debug

  engine:
    module: Simple
    config:
      host: localhost
      port: 11170

plugins:
  - module: Protocol::Gopher

今回は,ConfigDumpの動作テストをしたいだけなので必要最小限の設定にしています。

この設定を用いて実行すると以下のようになります。


$ ./gopper.pl -c config.yaml
Gopper [debug] setup engine Gopper::Engine::Simple
Gopper::Plugin::Method::ConfigDump [debug] ---
global:
  engine:
    config:
      host: localhost
      port: 11170
    module: Simple
  log:
    level: debug
plugins:
  - module: Protocol::Gopher
Gopper [debug] engine.preper

Gopper::Plugin::Method::ConfigDump [debug]の部分からconfigがdumpされました。 デーモンとして動作しているので,Ctrl-Cなどでgopper.plを強制終了して下さい。

pluginで追加されたメソッドがうまく動いた事が確認出来ましたね。この例を応用すればClass::Componentでのplugin作成は自在に出来ると思います。

Class::Component速報

今現在,Class::Componentのバージョンアップに向けた実装を行っています。予定としては,内部的な処理の変更,便利系componentの追加,pluginの初期化処理の一部変更を予定しています。それほど大きな変更にはならず,過去のバージョンとも互換性が保たれる予定です。

次回予告

今回は,Perlで利用出来るattributeの概念や活用方法,それを利用したClass::Componentでのplugin作成方法について解説を行いました。次回は,このattrbiteの話を掘り下げた話題と,Class::Componentでのattributeに独自attributeを実装する方法を紹介する予定です。

著者プロフィール

大沢和宏(おおさわかずひろ)

開発3センター サービス開発3室。翻訳Botなど,初期のBotサービス関連の開発を担当,その後LINE Taiwanのサービスを経て,現在はLINE LIVEのサーバ開発を行っている。

URL:https://github.com/yappo/