2011-02-25 5 views
4

내 무스 클래스의 속성에 대해 Str을 DBIx :: Class :: Row 객체로 강제 변환하려고합니다. 이렇게하려면 행을 찾기 위해 DBIC 스키마를 조회해야합니다. 조회가 실패한 경우 ArrayRef 속성에 오류를 푸시합니다.무스 강제로 내 개체의 속성에 액세스하려면 어떻게해야합니까?

현재 스키마에 클래스를 전달합니다.

강요하면 개체에 액세스 할 수 없으므로 오류 배열 arrayref 특성을 사용하거나 스키마 개체를 사용하여 조회를 수행 할 수 없습니다.

대체 방법은 '둘러보기'를 사용하여 조회 할 때 속성을 설정하는 것이지만 속성 값이 생성자를 통해 전달 될 때 호출되지 않습니다.

가능합니까? 아니면 달성하려는 작업을 수행 할 수있는 대체 구현이 있습니까?

답변

4

속성 이니셜 라이저을 사용하여 생성자에 전달 될 때 저장된 값을 캐치하고 변경할 수 있습니다. (그러나 속성은 생성자에서 설정 될 때만 실행되며 다른 시간에는 실행되지 않습니다.) 초기화 자용 문서는 Class::MOP::Attribute에서 찾을 수 있습니다.

이 속성은 생성자를 통해 속성이 설정된 경우에만 적용되므로 속성이 설정된 다른 경우를 catch해야합니다. 이것은 자동 생성 접근 감싸, 당신이 말한대로 방법을 수정하여 수행 할 수 있지만 하나의 방법으로 두 가지를 결합 할 수 있습니다 :

has my_attr => (
    is => 'rw', 
    isa => 'DBIx::Class::Row', 
    initializer => 'my_attr', 
); 

# my_attr is the autogenerated accessor - we method-modify it to mutate the 
# value being set, and catch cases where it is called as an initializer. 

# called for reads, writes, and on initialization at construction time 
around 'my_attr' => sub { 
    my $orig = shift; 
    my $self = shift; 
    # value is not defined if being called as a reader 
    # setter and attr are only defined if being called as an initializer 
    my ($value, $setter, $attr) = @_; 

    # the reader behaves normally 
    return $self->$orig if not @_; 

    # convert the string to the row object 
    my $row = $self->convert_str_to_row_obj($value); 

    # if called as an initializer, set the value and we're done 
    return $setter->($row) if $setter; 

    # otherwise, call the real writer with the new value 
    $self->$orig($row); 
}; 
+0

흠 -이 그것을 할 것이라고 생각하지만 난 그것을 시도 할 때 나는 '취득 특성 (my_attr)이 다음과 같은 이유로 유형 제약 조건을 전달하지 않습니다. 'DBIx :: Class :: Row'의 값이 Foo '인 경우 유효성 검사가 실패했습니다. 형식 제약 조건은 이니셜 라이저 메서드가 실행되기 전에 확인됩니다 * 나타납니다? – cubabit

+0

isa를 'Str | 목적' – cubabit

관련 문제