Class::Accessor::LiteやClass::Accessor::Lite::Lazyのように使えて, 型の恩恵を受けられる, Class::Accessor::Typedというモジュールを昔書きました.
詳しくは, 昔Kichijoji.pmで紹介した時に使った資料をまとめたものがあるので, こちらをご覧頂ければと思います.
このモジュールは大変便利なんですが, 1つ課題がありました. それは独自の型をうまくいい感じに使う方法が当時の自分には思い浮かばなかった... ということです.
例えば, 次のような Types.pm
があり, ここで「正の整数」であるPositiveInt
という型を定義していたとします.
package Types; use strict; use warnings; use Mouse::Util::TypeConstraints; subtype 'PositiveInt', as 'Int', where { $_ > 0 }, message { '0以上の整数でなければなりません' };
Class::Accessor::TypedでこのPositiveInt
を使うには, 常にTypes
を一緒にuseしないといけません(そうしなければ, Class::Accessor::TypedがPositiveIntの定義を見つけられないからです).
package Pkg; use strict; use warnings; # これがないと, 次のようなエラーが発生する: # 'baz': Validation failed for 'PositiveInt' with value 1 at # ... use Types; use Class::Accessor::Typed ( rw => { baz => 'PositiveInt', }, new => 1, ); 1;
ちょっと面倒ですね. この辺りで悩んでいて, プロダクト開発に導入するにあたって悩んでいたのですが, ふと思いつきました. それは, 次のようなパッケージを用意して, これを使うようにするというアイデアです:
package MyClassAccessorTyped; use Types; use Class::Accessor::Typed; sub import { goto \&Class::Accessor::Typed::import } 1;
こうすると, MyClassAccessorTyped
をuseするだけで事足りるようになります(use Types;
しなくても意図通りに動作する).
package Pkg; use strict; use warnings; use MyClassAccessorTyped ( rw => { baz => 'PositiveInt', }, new => 1, ); 1;
本来はClass::Accessor::Typed単体で綺麗に扱えるようにするべきなのでしょうが, 今のところかっこいい解決策が思いついていないので, この手で回避するのがいいのではないか, と思っています. ちょっとダサい(?)感じもしますが, Class::Accessor::LiteやClass::Accessor::Lite::Lazyで型の恩恵を受けられるのはそのダサさ(?)を超えるメリットがある... と思っています. この機会に是非Class::Accessor::Typedをお試し頂ければ幸いです.
また, Class::Accessor::Typedから独自の型をいい感じに使えるようにする問題について, 良いソリューションがありましたら, TwitterやPull Requestでご意見をお寄せ頂けると幸いです. よろしくおねがいします.