2016-12-02 9 views
3

Perl5의 대부분과 마찬가지로 해당 속성에 대해 사용자 정의 유형 변환을 지원하는 클래스를 만드는 방법은 여러 가지가 있습니다. 다음은 간단한 하나가 배열 참조에서 해시에,이다 :Perl6 클래스 속성의 유형 강제 변환

#!/usr/bin/env perl 

package Local::Class { 
    use Moo; 
    use Types::Standard qw(HashRef ArrayRef); 

    has set => (
    is => 'ro', 
    coerce => 1, 
    isa => HashRef->plus_coercions(
     ArrayRef, sub { return { map { $_ => 1} @{$_[0]} } }, 
    ), 
); 
} 

my $o = Local::Class->new({ set => [qw(a b b c)] }); 
# $o->set now holds { a => 1, b => 1, c => 1} 

나는 그것이 내가 필요한 것 같아 Perl6,이 같은 포트 뭔가 노력했습니다 것은 SetHashArray을 강제하는 방법입니다 . 지금까지, 나는 그 일을 할 수 있었던 유일한 방법은 다음과 같이이다 :

#!/usr/bin/env perl6 

class Local::Class { 
    has %.set; 
    ## Wanted to have 
    # has %.set is SetHash; 
    ## but it dies with "Cannot modify an immutable SetHash" 

    submethod TWEAK (:$set) { 
    self.set = $set.SetHash; 
    } 
} 

my $o = Local::Class.new(set => [< a b b c >]); 
# $o.set now holds {:a, :b, :c} 

을하지만이 작은 세부 사항에 대한 최소한, 그것을 할 올바른 방법으로 나에게하지 않는 것 홀수 번호의리스트를 생성자에 전달하면 스크립트가 죽게됩니다.

이렇게 Perl6에서 어떻게 이루어 집니까? 클래스 속성에 대한 사용자 정의 유형 강제 변환을 구현하는 데 권장되는 방법은 무엇입니까?

답변

3

TWEAK이 개체가 BUILD에 의해 초기화 된 후에 실행되며, 홀수 번호 배열을 제공하는 것이 폭발합니다.

BUILD 시간으로 강제 이동

, 사물이 예상대로 작동합니다 :

class Local::Class { 
    has %.set; 
    submethod BUILD (:$set) { 
    %!set := $set.SetHash; 
    } 
} 

당신이 자동 속성 초기화 조합에 강요 SetHash() 매개 변수 유형을 사용할 수 있다면 좋을 텐데, 그러나 이것은로 실패합니다 sigil은 속성의 이름의 일부이며 비 연관 형을 허용하려는 경우 매개 변수는 %-sigilled 일 수 없습니다. @smls으로

class Local::Class { 
    has $.set; 
    submethod BUILD (SetHash() :$!set) {} 
} 

지적,

class Local::Class { 
    has %.set is SetHash; 
    submethod BUILD (:$set) { 
    %!set = $set.SetHash; 
    } 
} 
이 가

아마 잘 작동한다 다음 변형 : 당신이 대신 $ -sigilled 속성을 사용하는 경우

그러나, 그것을 잘 작동합니다 으로 죽어가는 대신 불변의 SetHash을 수정할 수 없습니다.

SetHash가 할당되지 않는에 대한 해결 방법, 당신은 내가 실제로 작업을하기로 생각

class Local::Class { 
    has %.set is SetHash; 
    submethod BUILD (:$set) { 
    %!set{$set.SetHash.keys} = True xx *; 
    } 
} 
+2

를 사용할 수있는 바와 같이 '%의은 .set이 SetHash이다가,뿐만 아니라'및 '불변의 SetHash를 수정할 수 없습니다 "그냥 Rakudo 버그입니다. – smls

+1

@smls : agree; cf edit – Christoph

+1

'submethod BUILD (SetHash() : $ set) {%! set : = $ set}'도 잘 작동합니다. –