MooseのBUILDARGSで
URIオブジェクト作るんだけど、プロパティとしても同じことができないかなんとかしたい。おお、何言ってるのか分からない。
package WWW::ImagePager; use Any::Moose; use URI; has 'basepage' => (is=>'rw', isa=>'URI'); sub BUILDARGS { my ($self, %args) = @_; $args{basepage} = URI->new($agrs{basepage}); # ここと return { %args }; } around 'basepage' => sub { my $orig = shift; my $self = shift; return $self->$orig() unless @_; return $self->$orig(URI->new(shift)); # ここが同じプロパティなのに # 同じ処理でかぶってる… };
ただプロパティの値を途中で書き換えたいだけなのに…、えらい苦労。
use WWW::ImagePager; my $imagepager = WWW::ImagePager->new( basepage => 'http://www.google.co.jp/', ); $imagepager->basepage('http://www.yahoo.co.jp/');
うーん、is=>'rw'にしているのが問題なのかなぁ。でもここだけは書き換え可能にしたいところ。
※2011/7/5 追記
id:gfxさんからはてブコメントいただきました。いえっふーい!!
coerce使うのがいいんじゃないすかね。 e.g. https://gist.github.com/1063372
なんとぅぉー! そぉぅかー! coerceってなんかもっとこう、型チェックに使うイメージしか残ってなかったから使い方がよくわからないままモダパーで読み流してたところだったぜぃ!
さて。
書き直してみる。
とその前に、JPAの日本語資料読んでみた。(最初から読んどけって話ですよね、すみません)
Moose::Cookbook::Basics::Recipe5 Moose(0.92) - Japan Perl Association ドキュメント和訳プロジェクト
わざわざsubtypeを作る理由はなんだろうと思っていたので、丁度その回答にもなった。
ここではHTTP::Headersを直接型として利用するのではなく、サブタイプを作っています。これは、型変換はグローバルなものであるため、RequestクラスでHTTP::Headersの型変換を定義すると、同じPerlインタプリタ上でMooseを使っている「すべての」クラスで同じ型変換が定義されてしまうためです。このような名前空間の汚染は避けるのがベストプラクティス (Moose::Manual::BestPractices)です。
ほおなるほど。ここだけで使うならここだけで始末しろと。
隣の家の庭まで散らかすなと。
package WWW::ImagePager; use Any::Moose; use Any::Moose '::Util::TypeConstraints'; # 'subtype()', 'coerce()' use URI; my $subtype_uri = subtype __PACKAGE__.'::URI' # => as 'URI'; => as class_type('URI'); coerce $subtype_uri => from 'Str' => via { URI->new($_) }; has 'basepage' => (is=>'rw', isa=>$subtype_uri, required=>1, coerce=>1); __PACKAGE__->meta->make_immutable; # return 1;
こんな感じでちゃんと動きました!
BUILDARGSもaroundもでぃふぁいあもこの目的には不用でした。
gfx!thx!