[続き]Scala Macro Annotationによるコンフィギュレーション・アイテムのバインド


v0.1.2
前編に続き、@連城404の転送によりテキスト:
@連城404:おもしろくて、@conf val port=0の「=0」を外して現実的なタイプの説明に変える可能性はありますか?すなわち@conf port:Intという付与値はここでは全く実用的な意味がなく,制限を実現して導入されたノイズのようなものである.
class Server {
  @conf val port = 0 
  //           ,     :
  // @conf val port: Int
}

確かに必要ありませんが、意味はあります:IDEは間違いを報告しません.(少なくとも私が使っているIDEA 14のscala pluginではScala Macroはサポートされていません)= 0は外してもいいですか?
答えはいいですが、@連城404に聞かれたとき、私はまだ方法を考えていませんでした.
解決方法は実は難しくなくて、前提はScala ASTに対してよく知っていることです.
調査:
case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree)
Modifiersにはflagsの属性がある、ここではval portの種々の特徴がマークする.val port: Intval port = 0の違いはflagsから表れる.
class ModifierFlags {
  final val DEFERRED      = 1 << 4        // was `abstract' for members | trait is virtual
  final val DEFAULTINIT   = 1L << 41      // symbol is initialized to the default value: used by -Xcheckinit

  ...
}
ModifierFlagsにはすべてのflagsの値が定義、ここでは2つの列挙が上記の2つの異なる書き方に対応することを抜粋する.
具体的に実現するコードの提出は、0475d92cを参照する.
どのようにしてこれらの詳細を発見しますか?
  • print(x)、未知のオブジェクトの表示情報を探査し、多くの場合重要な手がかりを提供することができる.
  • print(x.getClass)、上の方法は役に立たないので、そのタイプを明らかにして、それからソースコードをひっくり返す必要があります.

  • v0.2.0
    上のv0.1.xValDefに基づく声明スタイルで、実際に使用すると次のことがわかります.
    作成が簡単であると同時に、クラス名定義が構成パスと厳密に一致するのは、すべてのシーンに適しているわけではありません.
    例えば、Kafkaと書かれた消費クライアントは、アクセスサービスの構成項目を設計します.
    kafka_broker {
      host = 10.0.0.1
      port = 12306
    }
    

    この場合、対応するクラス名がKafkaBrokerであることは明らかに設計意図に反し、KafkaConsumerのように最も自然な選択である.
    命名に多くの時間を費やすよりも、より良い宣言方法を変えたほうがいい.@confパラメータを使用して、デフォルトのコンフィギュレーション・アイテムのパスを変更できます.
    class KafkaConsumer {
      @conf("kafka_broker.host") val host: String
    }
    

    ええ、いいですね.問題を解決できます.ただ一周してまた帰ったような感じでした:
    class KafkaConsumer {
      val host = conf.getString("kafka_broker.host")
    }
    

    この二つの書き方に比べて、前者はあまり優位ではないようだ.Macro Annotationによるコンフィギュレーション・アイテムのバインドを解決する目的は、コードのメタ情報とコンフィギュレーション・アイテムとのマッピング関係を確立し、中間文字列のHard Codeによる再構築に伴う追加コストを低減することである.
    そのため、もう一つの書き方が誕生し、このAdding Reflection to Scala Macrosに啓発された.
    その詳細については、v0.2.0READMEを参照してください.
    この新しい書き方には、コードからプロファイルを生成することが容易であり、エスケープのコストが小さいという利点がある.
    うん...sbt pluginと書きましょう.