先日、といっても、一週間ほど前になってしまいましたが、Util::Anyの0.17をリリースしました。細かくバグってて、あーもーと思って、0.15のコードを見直したら、なんだこりゃって状態だったので、整理しました。リリースするレベルじゃなかったです。ごめんなさいm(__)m
で、0.16でOKと思ってたのですが、プロダクション環境で使ってくれている人からバグレポートがあり。調べたところ原因はtypo...という。テストも追加してるんですが、整理した方が良いな...。
で、直したよって言って、Changesをコピペしたメールを投げたら,Changesも2箇所typoしてて,"try less coffee Kato. :-)"って言われました orz
というわけで...最近付いた機能です。
- プラグイン
- Sub::Exporter的関数ジェネレータまわりの改善
プラグイン
プラグインは最初どうかなと思ってたのですが、つけました。Util::Allの方で大きめのモジュールを集めてたら、-all時のロードが遅くなっちゃってたので。{plugin => 0} と最後にオプションを与えてやると、ロードしないようにしました。なお、Util::Any には、pluginは作れません。自分のユーティリティモジュール作る際に使います。
package Util::Yours; use Util::Any -Base, -Pluggable;
のように、-Pluggableを指定します。プラグインは下記のように書きます。
package Util::Yours::Plugin::Net; sub utils { return { -net => [ [ 'Net::Amazon', '', { amazon => sub { my ($pkg, $class, $func, $args) = @_; my $amazon = Net::Amazon->new(token => $args->{token}); sub { $amazon } }, } ] ] }; } 1;
Sub::Exporter的関数ジェネレータ
結構便利でUtil::Allで、使ってます。下記の、now、years、months、hourは、この関数ジェネレータを使ってます。
use Util::All -datetime; my $dt = now + years 5 + months 10 + hour; # 今から5年10ヶ月と1時間後のDateTimeオブジェクト
ところで、DateTime::Duration には、end_of_month ていう、微妙なオプションがあります(デフォルトが微妙なので、Util::Allではデフォルトがlimitです)。こいつをまとめて指定することが出来ます。
use Util::All -datetime => {-args => {end_of_month => "preserve"}};
のようにします。これで、years、months ほか、定義されているモジュールに初期値としてこれが渡ります。
実際、上で書かれている関数はどのように定義されているかというと(※自動生成しているコードなんで、若干変なところがあります)。
'-datetime' => [ [ 'DateTime', '', { 'now' => sub { sub () { 'DateTime'->now(@_) } }, # 略 } ], [ 'DateTime::Duration', '', # 略 { 'month' => sub { my($pkg, $class, $func, $args, $kind_args) = @_; sub () { 'DateTime::Duration'->new('months', 1, 'end_of_month', $$kind_args{'end_of_month'} || $$args{'end_of_month'} || 'limit'); } }, 'years' => sub { my($pkg, $class, $func, $args, $kind_args) = @_; sub ($) { 'DateTime::Duration'->new('years', shift @_, 'end_of_month', $$kind_args{'end_of_month'} || $$args{'end_of_month'} || 'limit'); } }, # 略 } ],
最初のuseの引数の{ -args => {end_of_month => "preserve"}} の部分は、$kind_args で取れます。
$args は、個別に渡されている引数です。これは、下記のようにして渡します。
use Util::All -datetime => [years => {end_of_month => "preserve"}]
のようにすると、years の$argsに渡ります。datetimeの場合は、一括で渡すケースが多いと思いますが。
個別に渡す場合というのは、例えば下記のような場合でしょうか。
'-basecalc' => [ [ 'Math::BaseCalc', '', { 'to_base' => sub { my($pkg, $class, $func, $args, $kind_args) = @_; sub { 'Math::BaseCalc'->new('digits', $$kind_args{'digits'} || $$args{'digits'})->to_base(shift @_); } ; }, 'from_base' => sub { my($pkg, $class, $func, $args, $kind_args) = @_; sub { 'Math::BaseCalc'->new('digits', $$kind_args{'digits'} || $$args{'digits'})->from_base(shift @_); } } } ] ],
で、
use Util::Yours -basecalc => [ to_base => {-as => "to_base16" , digit => [0..9, "a" .. "f"]}, from_base => {-as => "from_base16", digit => [0..9, "a" .. "f"]}, to_base => {-as => "to_base2" , digit => [0, 1]}, from_base => {-as => "from_base2", digit => [0, 1]}, ]
みたいにして、-as で独自の関数名を渡してやれば、その名前で関数がExportされます。
print from_base16(to_base16(255)); print from_base2(to_base2(8));
みたいなことが出来たります。他の実例は、Util::Allに結構あります。
このへんはSub::Exporterを見て、便利だなぁと思ってつけた機能なんで、興味のある方は、Sub::Exporterも見てみるといいんではないでしょうか。
もう、だいたいやること終わった感があるのですが、次やるとしたら、種類ごとの初期化か、関数から種類、モジュールの逆マッピングかなと思っています。