2

私のDSLでは、次のようにできるようにしたいと思います。

val a = 5

Parse("TYPE") {
  a match {
    case 3 => info("almost")
    case s: String => error("wrong type")
    case 5 => info("you won!")
    case _ => error("omg")
  }
}

出力付き

[INFO] TYPE: you won!

ここで、は、およびメソッドParseを持つ関数オブジェクトです。apply(String)info(String)error(String)

object Parse {

  def apply(name: String)(parseF: => Unit) { parseF }
  def info(text: String) { println("[INFO] " + name + ": " + text) }
  def error(text: String) { println("[ERROR] " + name + ": " + text) }

}

秘訣は、メソッドinfoerrorメソッドの出力が何らかの形でParseオブジェクトにネイティブであり、上記の例でメッセージを作成する必要があることです。したがって、彼らは

  1. インポートなしで、例のようにアクセス可能である必要があります。
  2. 渡される最初の引数Parse()(例では「TYPE」)にアクセスできる必要があります。
  3. 作業中にインスタンスや追加のオブジェクトを作成してはなりません。

これは理想的な説明です。もう少し定型文が必要になると思います。提案してください、どうすればそれを達成できますか?

編集:メソッド内でメソッドinfoとメソッドを宣言する最初の推測では、渡されるメソッドでそれらが表示されません。まあ、当然のことながら..errorapplyparseF

4

2 に答える 2

2

多分このようなもの:

object Parse {
  val currentName = new util.DynamicVariable("<none>")
  def apply(name: String)(parseF: => Unit) = currentName.withValue(name)(parseF)
  def info(text: String) = println("[INFO] %s: %s" format (currentName.value, text)
}

// usage
import Parse._ // there's no other way to get ability to call 'info' without 'Parse'.
Parse("TYPE") {
  // some code
  info("some info") // prints: [INFO] TYPE: some info
}

info("some other info") // prints: [INFO] <none>: some other info

必要に応じて、ブロックinfo外で呼び出された場合、スロー例外を簡単に作成できます。Parse {}

于 2012-09-19T11:29:26.927 に答える
1

1-3を満たす解決策はありません。構文が少し異なる1と2または2と3を使用できます。

1と2)

class Parse(val s:String) {
  def info....

}

new Parse("TYPE") {

}

2と3)

object Parse {
  def apply(s:String)(f:String=>Unit) = ...
}

Parse("TYPE")(s => {

})
于 2012-09-19T12:12:14.970 に答える