글
IT/Perl 2008.06.07 14:27[ Perl ] Perl 로 OOP 하지 않겠나(요)? - Moose #3 - 형태에 관한 이야기
지난번에는 Moose 의 상속에 대한 이야기를 해봤습니다. 사실 이것저것 빼먹고 가는 것이 많기 때문에, 개인적으로 좀 더 알아봐주셨으면 하는 심정이 있고, 좀 더 알아보자 라고 했을 때 좀 지루할 것 같아서... 일단 원리를 알고 쓰기보다는 쓰면서 원리를 알아가는 게 더 쉬운 방법인 것 같기도 합니다.
2008/06/02 - [IT/Perl] - [ Perl ] Perl 로 OOP 하지 않겠나(요)? - Moose #1-2
여기에서 isa 에 들어가는 형태에 대한 언급이 있었고, Int 에서 문자열 쓰면 에러난다는 등의 해서는 안될 짓에 대한 이야기를 한 적이 있습니다. 이번에는 형태에 대한 좀 더 자세한 이야기입니다.
package Me2day::Request;
use Moose;
use Moose::Util::TypeConstraints;
subtype 'URI' # 자기가 정의하고픈 형태의 이름
=> as 'Object' # 계승한 형태
=> where { $_->isa('URI') }; # 형태의 Validation 체크
has 'uri' => (is => 'rw', isa => 'URI');
1;
use Moose;
use Moose::Util::TypeConstraints;
subtype 'URI' # 자기가 정의하고픈 형태의 이름
=> as 'Object' # 계승한 형태
=> where { $_->isa('URI') }; # 형태의 Validation 체크
has 'uri' => (is => 'rw', isa => 'URI');
1;
일단 가장 간단한 예제를 주워와봤습니다. 이런 'URI' 같은 자신이 직접 형태를 정해줄 경우에는
use Moose::Util::TypeConstraints;
이 필수입니다. 그런 다음에는 자기 나름대로 URI 이라는 형태를 지정해 줍니다.
subtype 'URI'
=> as 'Object'
=> where { $_->isa('URI') };
이제 uri 접근자는 URI가 아니면 받아들일 수 없게 되어버립니다. 이 말인 즉슨...=> as 'Object'
=> where { $_->isa('URI') };
my $blah = Me2day::Request->new( 'uri' => 'http://jeen.tistory.com' );
일 때, uri 의 값을 문자열인 http://jeen.tistory.com 으로 지정했습니다. 이러면 자신이 정의한 URI 의 타입에 맞지 않게 됩니다. URI 는 Object 이기를 기대하며, URI 모듈을 사용하기를 원하고 있죠. 그럼 이 입맛에 맞춰주면 됩니다.
my $blah = Me2day::Request->new( 'uri' => URI->new('http://jeen.tistory.com') );
그러면 이제 화를 내지 않는 우리의 Moooooose ~
Moose 특유의 뿔 처럼 엄격함만을 강조하는 것이냐면, 그럴 수도 있습니다만, 여기서 더욱 유연하게 처리해줄 수 도 있습니다.
coerce 'URI'
=> from 'Str'
=> via { URI->new($_) }
=> from 'Int'
=> via { blahblah... }
coerce 를 사용하는 것입니다. 이러면 URI 속성을 사용하는 접근자에 문자열('Str') 이 올때에는 URI 모듈을 사용해서 부르게 됩니다. 이때는 여러 상속형태에 대해서 강제변경을 지정할 수 있습니다.=> from 'Str'
=> via { URI->new($_) }
=> from 'Int'
=> via { blahblah... }
여기서 중요한 것은 coerce 를 사용해서 강제로 형태변경할 경우에는 접근자에 옵션을 하나 더 추가해줘야 합니다.
has 'uri' => (is => 'rw', isa => 'URI', coerce => 1);
이렇게 말이죠.전체코드입니다.
package Me2day::Request;
use Moose;
use Moose::Util::TypeConstraints; # 아래와 같은 일을 하려면 반드시!
use URI;
subtype 'URI' # 자기가 정의하고픈 형태의 이름
=> as 'Object' # 계승한 형태
=> where { $_->isa('URI') }; # 형태의 Validation 체크
coerce 'URI' # 강제 형태변경
=> from 'Str' # 이런 타입이 오면
=> via { URI->new($_) }; # 이렇게 해줘야지.
has 'uri' => (is => 'rw', isa => 'URI', coerce => 1);
1;
my $blah = Me2day::Request->new ( uri => 'http://jeen.tistory.com' );
print $blah->uri."\n"; # http://jeen.tistory.com
print $blah->uri->scheme; # http
use Moose;
use Moose::Util::TypeConstraints; # 아래와 같은 일을 하려면 반드시!
use URI;
subtype 'URI' # 자기가 정의하고픈 형태의 이름
=> as 'Object' # 계승한 형태
=> where { $_->isa('URI') }; # 형태의 Validation 체크
coerce 'URI' # 강제 형태변경
=> from 'Str' # 이런 타입이 오면
=> via { URI->new($_) }; # 이렇게 해줘야지.
has 'uri' => (is => 'rw', isa => 'URI', coerce => 1);
1;
my $blah = Me2day::Request->new ( uri => 'http://jeen.tistory.com' );
print $blah->uri."\n"; # http://jeen.tistory.com
print $blah->uri->scheme; # http
물론 uri 의 값은 URI->new('http://jeen.tistory.com') 를 써도 됩니다. 이건 subtype 에서 기본적으로 바라고 있는 값의 형태이기 때문입니다.
이쯤에서 다른 예제를 불러오도록 하죠.
package Me2day::Request;
use Moose;
use Moose::Util::TypeConstraints;
use Digest::MD5;
subtype 'Encrypt'
=> as 'Str';
coerce 'Encrypt'
=> from 'Str'
=> via {
my $nonce = sprintf "%08x", rand(16 ** 8);
$nonce.Digest::MD5->new->add($nonce.$_)->hexdigest;
};
has 'username' => (is => 'ro', isa => 'Str', required => 1);
has 'password' => (is => 'ro', isa => 'Encrypt', required => 1, coerce => 1);
1;
my $blah = Me2day->new ( username => 'jeen', password => '22830' );
print $blah->password; # 65dfb0a73f23368b4701a2435d8a64cabd26762b
use Moose;
use Moose::Util::TypeConstraints;
use Digest::MD5;
subtype 'Encrypt'
=> as 'Str';
coerce 'Encrypt'
=> from 'Str'
=> via {
my $nonce = sprintf "%08x", rand(16 ** 8);
$nonce.Digest::MD5->new->add($nonce.$_)->hexdigest;
};
has 'username' => (is => 'ro', isa => 'Str', required => 1);
has 'password' => (is => 'ro', isa => 'Encrypt', required => 1, coerce => 1);
1;
my $blah = Me2day->new ( username => 'jeen', password => '22830' );
print $blah->password; # 65dfb0a73f23368b4701a2435d8a64cabd26762b
어떤 별 다른 차이점도 없습니다. Me2day의 인증키 생성을 위한 처리를 coerce 'Encrypt' 에 담아서,
password 값이 들어오면 자동으로 인증키를 만들고 그 값이 password 의 값으로 강제변경되는 것입니다. 위에서 언급을 빼먹었는데. coerce 를 사용하기 위해서는 subtype 이 지정되어 있어야 합니다.
이상으로 Moose 의 형태변경에 대한 이야기를 마치겠습니다.
'IT > Perl' 카테고리의 다른 글
[ Perl ] Catalyst 를 이용한 웹 서비스 개발 #1 (4) | 2008.06.09 |
---|---|
[ Perl ] Perl 로 OOP 하지 않겠나(요)? - Moose #3 - 형태에 관한 이야기 (4) | 2008.06.07 |
[ Perl ] Perl 로 OOP 하지 않겠나(요)? - Moose #2 - 상속 (0) | 2008.06.03 |
[ Perl ] Perl 로 OOP 하지 않겠나(요)? - Moose #1-2 (2) | 2008.06.02 |
RECENT COMMENT