2017-01-22 15 views
8

역할로 표현 복잡한 문법의 시리즈를 상상해 :Perl 6은 다른 출처에서 동일한 역할을 포함시킬 수 있습니까? 이 간단한 예제가 충돌을 보여주기 충분하지만

role Alpha { 
    token alpha { :i <[A..Z]> } 
    } 

role Digit { 
    token digit { <[0..9]> } 
    } 

role Either 
    does Alpha 
    does Digit { 
    token either { <alpha> | <digit> } 
    } 

grammar Thingy 
    does Either 
    does Alpha 
    { 
    token TOP { <alpha> <either>* } 
    } 

my $match = Thingy.parse('1a3'); 
dd $match; 

펄 (6)가 충돌 것을 알아낼 관계를 수습하지 않기 때문에이 작동하지 않습니다 동일한 소스에서 같은 일이 실제로 :

는 0123를 읽고, 여러 역할

에 존재하지만 때문에 방법 '알파'클래스 꼬추으로 해결해야, 참조 :

역할은 클래스에서 상속되지 않지만 다른 역할로 구성 될 수 있습니다. 그러나이 "crony"구성은 수업 구성 시간까지 평가되지 않습니다. 즉, 두 가지 역할이 동일한 역할을한다면, 충돌은 없습니다. 마치 클래스가 자신의 역할을 끌어 당기고 역할이 수행하지 않은 것처럼 말입니다. 역할은 설립 방법에 관계없이 결코 충돌 할 수 없습니다.

는 그 클래스 ThingyAlpha은 두 개의 서로 다른 부분에 포함되어 있는지 풀다 수있을 것입니다 수 있도록 역할, 가능한 늦게 적용되는 것을 의미 읽어 보시기 바랍니다. 이것은 최종 클래스를 구성하는 모든 역할 목록을 작성한 다음 최종 클래스에만 해당 목록을 적용하는 것과 같이 작동 할 것이라고 생각했습니다. 그런 식으로 Either과 같은 것은 정의한 것만 섞어서 나중에 합성하여 Alpha을 가져올 것입니다.

다양한 (IETF) RFC에 대한 문법을 ​​구현할 때이 문제가 발생했습니다. 많은 사람들이 다른 RFC의 문법을 참조하기 때문에 Perl 6이 C3에 의한 상속을 해결할 수 없습니다. 그래서 저는 역할이 관계를 끊을 것이라고 생각했습니다. 분명히 그렇지 않습니다.

+0

문법에 특별히 영향을 미치는 것이 있습니까? 다음은 똑같은 (그리고 예상대로) 실패합니다 :'perl6 -e 'role Foo {method bar {}}; 역할 Baz {방법 모음 {}}; class My :: Grammar {또한 Foo를 수행합니다. 바즈도 그렇다. } '' 그렇지 않으면 물론 스스로 해결할 수 있습니다 (역할에 대한 문서에서 언급 됨) :'token 호스트 {$ = <문법 :: IETF :: URI :: RFC3986 :: 호스트> [ ' : '<.port>]? }' – ugexe

+0

문법에 근본적으로 특이한 것은 아니지만 문법의 여러 부분에 나타날 수있는 명명 된 규칙에 대해서는 훨씬 더 유용합니다. 나는 문법이 거대 할 때 거대한 엉망이기 때문에 나 자신을 해결하지 않을 것입니다. –

+2

제목의 질문에 대한 대답은 "그렇습니다."입니다. –

답변

3

예, Perl 6은 다른 출처에서 동일한 역할을 포함시킬 수 있어야합니다. role

간단한 definition들입니다 :

역할은 클래스 사이에 공유 할 수있는 행동이나 상태의 일부 조각을 캡슐화합니다.

또는

역할은 행동의 이산 컬렉션의 이름입니다.

자, 우리가 물에 떠내려 할 수있는 개체에 대한 Floatable 행동 및 항해 할 수있는 개체에 대한 Sailable 동작을 가정 해 봅시다. 당연히 항해 할 수있는 물체를 떠있을 수 있습니다. Sloop은 자연적으로 착석 가능하고 사용할 수 있습니다. 동일Floatable의 동작이 FloatableSailable 역할로 전달된다는 사실에는 아무런 충돌이 없습니다.예상대로 펄에서

,이 (그것뿐만 아니라 Moose와 함께 작동) 작동 :

#!/usr/bin/env perl 

use v5.24; # why not 
use warnings; 

package Floatable { 
    use Moo::Role; 
    sub float { say "float" } 
} 

package Sailable { 
    use Moo::Role; 
    with 'Floatable'; 
    sub sail { $_[0]->float; say "sail" }; 
} 

package Sloop { 
    use Moo; 
    with qw(Floatable Sailable); 
} 

my $s = Sloop->new; 

$s->sail; 

이 동작은 직관적으로 분명 하나입니다.

역할을한다는 점에서 그들은 속성과 메소드의 컬렉션은 클래스와 비슷한 방법으로 다음과 같습니다 Perl6 documentation for roles을 볼 때 내가 발견

하나의 문제는 간단한 한 문장 정의의 부족이다. 그들은 역할이 객체의 행동의 일부만을 기술하고 역할이 클래스에 어떻게 적용되는지에 대해서도 의미가 다릅니다. 또는 다르게 표현할 때 클래스는 객체를 관리하기위한 것이고 역할은 동작 및 코드 재사용을 관리하기위한 것입니다.

...

역할 응용 프로그램은 클래스 상속에서 크게 다르다. 역할이 클래스에 적용되면 해당 역할의 메소드가 클래스에 복사됩니다. 동일한 클래스에 여러 역할이 적용되면 충돌 (예 : 동일한 이름의 속성 또는 다중이 아닌 메소드)으로 인해 컴파일 타임 오류가 발생합니다.이 오류는 클래스에 동일한 이름의 메소드를 제공하여 해결할 수 있습니다. perl6동일한 동작을 제공하는 두 가지 역할을 발견 한 경우

은 분명히, 내가 무리 찾을 수있는 방법으로 충돌로이 생각한다.

참고 다음 예제 미묘한 차이 : 두 가지 역할이 같은 동작을 제공하기 위해서 항에 원하기 때문에이 경우

#!/usr/bin/env perl 

use v5.24; # why not 
use warnings; 

package Floatable { 
    use Moo::Role; 
    sub float { say "float" } 
} 

package Sailable { 
    use Moo::Role; 
    sub float { say "floating bonds to finance journey "} 
    sub sail { $_[0]->float; say "sail" }; 
} 

package Sloop { 
    use Moo; 
    with qw(Floatable Sailable); 
} 

my $s = Sloop->new; 

$s->sail; 

는 충돌이 예상 될 것입니다.