3

一部のコードを Scala 2.10-M5から Scala 2.10-M7に移行しています。マクロ コンテキストの Type API が大幅に削減されていることがわかりました。特に、基になる定義と typeArgs 定義を取得する方法を考えます

--

更新しました

@EugeneBurmako のリクエストに応じて、全体像を表示します。次の状態があるとします。

class Attribute[C[_], E]

class Id[E]

trait Entity {
  val att1: List[Int]
  val att2: Int
}

object Entity {
  val att1reif = new Attribute[List, Int]
  val att2reif = new Attribute[Id, Int]
}

def Let[T <: Entity, C[_], E](en: T, att: Attribute[C, E], ce: C[E]): T =
  /* Updates the whole attribute */

def Let[T <: Entity, C[_], E](en: Entity, att: Attribute[C, E], e: E, mode: Boolean): T = 
  /* Adds or removes (mode) an item */

いくつかの属性をホストするエンティティがあります。エンティティ コンパニオン オブジェクトには、これらの属性に関するメタ情報 (具体化) が含まれています。Letファミリでは、(新しいコピーを作成することによって) エンティティを更新できます。

ここまでは順調ですね。Let メソッドは次のように使用できます。

val ent = new Entity { val att1 = List(); val att2 = 3 }
Let(ent, Entity.att1reif, List(1, 2, 3)) // att1 = List(1, 2, 3)
Let(ent, Entity.att1reif, 4, true)       // att1 = List(1, 2, 3, 4)
Let(ent, Entity.att1reif, 1, false)      // att1 = List(2, 3, 4)

具体化属性は冗長であるため、ユーザーにはよりシンプルな API を使用してもらいたいと考えています。特に、次のもの:

// Same code as DSL
ent.att1 := List(1, 2, 3)
ent.att1 :+ 4
ent.att1 :- 1

具体化に関する情報はどこにもないことに注意してください。したがって、目標を達成するには、いくつかのヘルパーとマクロ ビューが必要です。

trait AttributeHelper {
  type T <: Entity
  type C[_]
  type E
  val ent: T
  val att: Attribute[C, E]
  def :=(ce: C[E]): T = Let(ent, att, ce)
  def :+(e: E): T = Let(ent, att, e, true)
  def :-(e: E): T = Let(ent, att, e, false)
}

def toAttributeHelperImpl[V: c.AbsTypeTag](c: Context)(expr: c.Expr[V]): c.Expr[AttributeHelper] = 
  /* A looong macro (currently broken), since I can't split V into C[_] and E,
   * which are needed to generate the expression that instantiates an *AttributeHelper*.
   * The macro is responsible of finding the attribute reification.
   */

私たちのマクロ定義は、実際にはビューであり、DSL 式を許可する魔法を行います。

implicit def toAttributeHelper[V](expr: V): AttributeHelper = macro toAttributeHelperImpl[V]

2 つの型パラメーターを使用するマクロを実行しようとしましたが、その間、暗黙的なビューは適用されません (コンパイラーは両方の型を推測できないため)。

そのため、最初に述べたように、M5 では利用可能でしたが M7 では利用できなかったtypeArgsの欠如が、以前のマクロを壊してしまいました。その定義を持たずに AttributeHelper 構造を生成するにはどうすればよいですか?

最後に、前のコードは簡略化したものに過ぎないと言わなければなりません。他にも関連する証拠がいくつかあります。そのため、基礎となるを使用する必要があります。

4

1 に答える 1

2

M5 の頃に行われたリフレクション API のクリーンアップの背後にある一般的な考え方は、非常に特殊化されたメソッドを削除することでした。

たとえば、typeArgsは型にのみ適用されるTypeRefため、基本型に保持する意味はあまりありませんType。置換は単純なパターン マッチです: tpe match { case TypeRef(_, _, args) => arg; case _ => Nil }.

underlyingただし、型の具体的なフレーバーに応じて多くのことを意味する内部実装の概念であるため、異なります。ユースケースについて詳しく説明していただければ、 の代替案を見つけるお手伝いができるかもしれませんunderlying

于 2012-09-25T17:18:10.197 に答える