2013-03-15 10 views
2

두 개의 Perl 모듈을 Moo으로 마이그레이션하기 시작했으나 setter/writer가 하나의 인수 만 가질 수 있기 때문에 멈추었습니다 (can not it?). 여기Perl Moo에서 setter/writter에 여러 인수를 전달하는 방법

package MyThing: 
use Moo; 
use Scalar::Util qw(blessed); 
use SomeOtherThing; 

has foo => (
    is => 'rw', 
    coerce => sub { 
     return $_[0] if blessed($_[0]) and $_[0]->isa('SomeOtherThing'); 
     return SomeOtherThing->new(@_); # does not work, because @_ == 1 
    },  
); 

을 간단한 사용 사례입니다 : 이것은 또한 강요에 적용

package MyApplication; 
use MyThing; 

$thing = MyThing->new; 
$thing->foo('some', 'values'); # would like to have this shortcut 
$thing->foo; # expected a SomeOtherThing 

# must use this ugly form instead 
$thing->foo(SomeOtherThing->new('some', 'values')); 

여러 인수 설정을 지원 접근을 구현하는 쉬운 방법이 있나요?

답변

4

예, 사용 배열 참조 : 객체가 키/값 인수를 사용할 필요가있는 경우 또한, 대신 hashref을 사용할 수

$thing->foo(['some', 'values']); 

use Carp; 
has foo => (
    is => 'rw', 
    coerce => sub { 
    return $_[0] if blessed($_[0]) and $_[0]->isa('SomeOtherThing'); 
    ref $_[0] && ref $_[0] eq 'ARRAY' or croak "foo: arg must be a SomeOtherThing or array reference"; 
    return SomeOtherThing->new(@{$_[0]}); 
    },  
); 

나중에

....

전체 무스를 사용하면 대신 ArrayRef에서 SomeOtherThing으로 유형 공동 작성을 작성합니다.


고지

I이 일부의 경우 (예를 들면 통과 X/Y 좌표를 대신 Point 객체를 생성) 유용한하지만주의 사용할 것이라고 볼 수

.

이이 수업의 결합이 증가 하 : MyThing 그냥 SomeOtherThing의 방법에 따라하지 지금뿐만 아니라 생성자 - 당신이 SomeOtherThing에 새 필드를 추가하는 경우, 당신은 모두 모든 모듈을 MyThing 변경해야 할 수도 있습니다를 그 MyThing의 foo 메소드를 호출하십시오. 아야!

+1

해결 방법을 제공해 주셔서 감사합니다. 여전히 해결 방법이지만 내가 찾고있는 것이 아닙니다. 나는 그것을 할 수있는 방법을 발견하고 perl 패키지를 만들었다 : https://github.com/nichtich/MooX-AutoConstructor – Jakob

1

세터의 여러 인수에 액세스 할 수 없으므로이 기능을 확장하는 Perl 모듈을 작성했습니다. 현재 실험 중이므로 Class::Accessor::Coerce at PrePAN을 자유롭게 말하십시오.