2012-06-28 3 views
5

케이크 패턴을 사용하는 프로젝트에서 일부 매크로를 통합해야합니다. 그 패턴 덕분에 우리는 다른 많은 이점들 중에서도 많은 수의 수입품을 피할 수있었습니다. 그래서 우리는 그것을 지키고 싶습니다. 이제 우리는 우리가 트렁크 밖에서 테스트 한 일부 실험 매크로에 문제가 있습니다. 먼저, 더미 시스템이라는 케이크를 보여주지 :Cake-Pattern과 매크로를 통합 할 수 있습니까?

trait APiece { 
    class A 
} 

trait BPiece { this: APiece => 
    def aMacro(a: A): Unit =() /* macro ??? */ 
} 

trait CPiece { this: APiece with BPiece => 
    def aMacroInvoker = aMacro(new A) 
} 

class Cake { this: APiece with BPiece with CPiece => } 

은 개당 클래스를 정의 BPiece은 낱개로 정의 된 클래스를 사용하는 매크로 있어야하는데, 마지막 CPiece 매크로를 호출합니다. BPiece는 구현을 코딩 할 수 없었기 때문에 매크로가되어야한다고했습니다. 나는 몇 가지 방법을 시도했지만 나는 항상 다음과 같은 오류와 충돌 :

"macro implementation must be in statically accessible object" 

macros code 하나는 정적 모듈에 매크로를 둘러싸 neccesary 것을 추측 할 수 읽기. 시스템 구조를 사용하는 매크로를 배포하는 방법이 있습니까?

답변

4

운 좋게도 문제를 쉽게 해결할 수 있습니다.

하지만 먼저 회고전을 드리겠습니다. 첫 번째 프로토 타입에서 매크로는 다음과 같이 정의되었습니다. def macro aMacro(a: A): Unit = .... SIP를 준비 할 때 매크로 정의 (매크로의 공개 얼굴)와 매크로 구현 (매크로 논리를 호스트하는 트리 변환기)을 분리하는 것이 가장 큰 발전의 하나입니다. 이것이 얼마나 멋진지를 깨닫는 데는 시간이 걸렸지 만 지금은 매크로 선언을 할 때마다 기쁨으로 빛납니다.

그래서 질문에 답하십시오. 물론 매크로 구현은 정적으로 액세스 할 수 있어야합니다 (그렇지 않으면 컴파일러가 컴파일 중에로드 및 호출 할 수 없습니다). 심지어 다른 컴파일 단위로 원하는 어떤 객체에 투입 될 수있는 정의에서라고

trait BPiece { this: APiece => 
    def aMacro(a: A): Unit = macro Macros.aMacro 
} 

매크로 구현 : 당신이 그런 정의를 쓸 수 있도록 그러나 매크로 정의는 이러한 제한이없는 .

유일한 누락 된 퍼즐 조각은 A이 케이크 내부에 정의되어 있기 때문에 구현에서 A을 어떻게 참조 할 것인가입니다.

(갱신 : 가장 간단한 방법은 aMacro 제네릭하고 형식 유추에 의존하는 것 2.10.0-M7에서이 예제가 제대로 작동되게하려면, 당신은 c.AbsTypeTag와 c.TypeTag를 교체해야이 예를 만들기 위해 2.10.0-RC1의 작품은 c.AbsTypeTag는

trait BPiece { this: APiece => 
    def aMacro[A](a: A): Unit = macro Macros.aMacro[A] 
} 

object Macros { 
    def aMacro[A: c.TypeTag](c: Context)(a: c.Expr[A]): c.Expr[Unit] = c.literalUnit 
} 

이것은 당신이 때문에 매크로 구현 A에 대한,하지만, reify을 사용 못하게없이 단지 형 매개 변수) c.WeakTypeTag로 교체해야합니다 모든 회원. 또한 매크로에서 케이크 관련 정보를 반환하려는 경우 문제가 발생할 수 있지만 문제가 발생하면 처리해 보겠습니다. 필요한 경우 후속 질문을 제출하십시오.

+2

나는 그의 문제를 해결할 것이라고 생각하지 않으며, 나는 아무것도 생각하지 않는다. 당신이 알아야 할 케이크 패턴의 본질! :-) - "클라이언트"코드에서 원하는 레이어를 선택할 수 있습니다. 'Macros'가 정적이라면, 당신은 그것을 자유롭게 바꿀 수 없습니다. 소스 파일이나 클래스 파일을 전환 할 수는 있지만 "여기에서 매크로를 사용하므로 매크로가 사용됩니다"라는 코드는 작성할 수 없습니다. –

+0

위대한, 나는 새로운 문제가 발생할 것 같아요,하지만 지금은이 솔루션으로 갈 수 있습니다. 고마워요!다니엘, 우리 시스템은 매크로로 순수하게 (케이크 패턴) 될 수 없습니다. 고객이 사용하기를 원할지 여부를 결정할 수 있습니다. 그래서 나는 이것이 충분히 좋기를 바랍니다. – jeslg

+0

@ DanielC.Sobral 생각은 케이크 안에 매크로를 선언하는 것이 었습니다. 서로 다른 매크로 구현을 나타내는 매크로를 정의하는 다른 레이어가있는 경우 원하는대로 다른 레이어로 전환하여 다른 동작을 얻을 수 있습니다. –

관련 문제