2013-10-31 9 views
0

나는 Eugene Burmako의 매크로 주석 예제를 Macro Paradise (덕분에 Eugene!)에서 사용했으며 val을 빈 클래스 here에 추가했습니다.스칼라 매크로 특수 효과 - 클래스를 형식 매개 변수로 사용하면 클래스가 업데이트 된 것처럼 보이는 이유는 무엇입니까?

예를 들어 새로운 val을 예상대로 호출 할 수 있습니다. 하지만 업데이트 된 클래스를 형식 매개 변수로 사용하려고하면 (예 : Salat (Scala sig를 파싱) 또는 Scalavro (2.10 리플렉션 사용)의 클래스는 여전히 비어 있습니다 (예 : val이 추가되지 않은 것처럼).

Salat가 Scala 서명을 구문 분석했기 때문에 정상적인 서명보다 약 30 개 항목이 짧았고 항목의 순서가 다릅니다. 그러나 에 서명에 추가 된 val에 대한 정보가 포함되어 나타납니다.

새 발 정보에 액세스 할 수없는 이유는 무엇입니까? 봐 주셔서 감사합니다.

답변

1

템플릿에 val을 추가한다고해서 자동으로 생성자 매개 변수가되는 것은 아닙니다. 이를 위해 생성자 자체도 조정해야합니다. 운좋게도 수동 트리 구조와 비교하여이 작업을 크게 단순화 한 쿼지 쿼트가 있습니다.

case q"$mods class $name[..$tparams](..$first)(...$rest) extends ..$parents { $self => ..$body }" :: Nil => 
    val CASEACCESSOR = (1 << 24).toLong.asInstanceOf[FlagSet] 
    val PARAMACCESSOR = (1 << 29).toLong.asInstanceOf[FlagSet] 
    val helloMods = Modifiers(CASEACCESSOR | PARAMACCESSOR | DEFAULTPARAM) 
    val helloVal = q"""$helloMods val x: String = "hello macro!"""" 
    q"$mods class $name[..$tparams](..$first, $helloVal)(...$rest) extends ..$parents { $self => ..$body }" 

참고 단점의 몇 : 1) 우리는 Salat에서 충돌을 피하기 위해 공식 API에 존재하지 않는 CASEACCESSOR 및 PARAMACCESSOR 플래그를 설정해야합니다, 2) 우리가 순서대로 DEFAULTPARAM를 설정해야 scalac이 기본 매개 변수를 기본 매개 변수로 인식하는지 확인하십시오. 3) 기본 매개 변수는 유추 된 유 형을 가질 수 없으므로 여기에 String을 명시 적으로 제공해야합니다.

+0

환상적! quasiquotes의 예가 필요했습니다. 감사합니다. (또한, 좋은 오류 메시지가 나를 괴롭히는 데 도움이됩니다.) 작업 예제를 보여주기 위해 프로젝트를 업데이트했습니다. –

+0

최신 쿼시 퀘스트로 caseaccessor | paramacessor 마술이 필요 없으며, 그 플래그는 자동으로 뒤에서 설정됩니다. –

+1

p.s. 사실 DEFAULTPARAM도 필요하지 않습니다. 그냥 val을 만들고 파라미터 위치에 연결하면됩니다. –