Practice of Programming

プログラム とか Linuxとかの話題

UtilをまとめてしまうUtil::Any

#coderepos で、「怪しい名前空間w」と言われてしまいましたが(^^;;


Util系のモジュールがPerlにいくつかあって、便利なんだけど、紛らわしいというか、覚えてなくて、毎度調べるみたいなことがあります。
たとえば、List::UtilとList::MoreUtils。


「uniq関数どっちやったけ...?」


みたいな。そんな、わずらわしさを解消するために、Util::Any というものを作ってみました。
まとめるだけじゃ芸が無いので、まとめるモジュールを自作しやすいようにしてみました。


CPAN
http://search.cpan.org/dist/Util-Any
CodeRepos
http://coderepos.org/share/browser/lang/perl/Util-Any/trunk/


使い方は非常に簡単。

use Util::Any qw/list/;

とすれば、List::MoreUtils, List::Util のすべての関数がimportされる。
関数を選びたければ、

use Util::Any {list => ['any', 'uniq']};

のようにしてやれば良いだけ。


他にも、Scalar::UtilとHash::Utilが使えますんで、

use Util::Any qw/scalar hash/;

のようにも使えます。面倒だ、全部よこせというときは、

use Util::Any qw/all/;

で、OK。


もう一つの使い方として、自分好みのUtiモジュールを作ることができます。
継承して、$Utils変数を定義するだけです。

package Util::Yours;

use base qw/Util::Any/;
use Clone qw/clone/;

our $Utils = clone $Util::Any::Utils; # clone してください
push @{$Utils->{string} ||= []}, qw/String::CamelCase/;

のようにしてやれば、

use Util::Yours qw/string/;

camelize("hoge_fuga");

のように、指定されたモジュールからimportできます。


上記のstringのように、list, scalar, hash の種類は自由に足せます(ハッシュのキーは小文字限定)。
たとえば、debug という名前にして、debug系のUtilを突っ込めるようにしてもいいかなぁとか。
※allだけは、特殊ですが


関数名衝突したら、どうすんねん。という話もありますが、prefixつけることができます。

use Util::Any qw/list/, {prefix => 1};

のようにしますと、関数名の前に、list_ というprefixがつきます。

list_uniq(1,1,2,2,3,3,3);

みたいな感じになるわけです。


種類ごとのprefixじゃ、足りない場合もあるでしょうから、モジュールごとのprefixもつけることができます。

package Util::Yours;

use base qw/Util::Any/;

our %Utils = %Util::Any::Utils;
push @{$Utils->{list}}, ['Your::Favorite::Util' => 'your_'];

のように、クラス名のスカラの変わりに、[クラス名 => 'prefix_']を指定します。コードでは、

use Util::Yours qw/list/, {module_prefix => 1};

your_util_function(...);

みたいに呼べるようになります。


ちなみに、Util::Any自体は、指定されたモジュールをrequireして、呼び出し側に、ExportToを使ってexportしてやるだけなので、$Utilsに登録してあるモジュールを全部読み込んでいたり、全関数をUtil::Anyにimportしていたりってことはないです。


最後に、開発動機その2。
PHPとか見ると、便利関数が揃っているようです(賛否色々ありそうですけど)。そういうのをPerlで集めようと思った場合、CPANで個別にインストール、そして、use を羅列...っていうのは、ちょっと敷居が高いというか、面倒というか。
そのために、Util::Anyを使って、Util系モジュールと種類の整理を行ってやれば、Util系関数を使うのが結構楽になるかも、とか思ったりしました。