在我的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) }
}
诀窍是info
和error
方法的输出应该以某种方式为Parse
对象生成,并通过示例构造消息,如上所示。因此,他们
Parse()
的第一个参数(示例中为“TYPE”)。这是一个理想的描述。我认为它需要更多的样板。请建议,我该如何实现?
编辑:我在info
方法中声明error
和apply
方法的初步猜测并未在parseF
中显示这些方法方法正在通过。嗯,不出所料......
答案 0 :(得分: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 {}
块之外调用,则很容易使{{1}}抛出异常。
答案 1 :(得分: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 => {
})