Created
June 26, 2012 02:58
-
-
Save sndyuk/2992994 to your computer and use it in GitHub Desktop.
Scalaでタスク管理DSL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package trampoline | |
import java.text.SimpleDateFormat | |
import java.util.Date | |
/** | |
* Simple Unit test DSL. | |
*/ | |
class UnitTestContext(val limit: Date) | |
class UnitTestDsl | |
object UnitTestDsl { | |
val dateFormat = new SimpleDateFormat("yyyy/MM/dd") | |
implicit def toTask[C](task: Bearer[C] => Bearer[C]) = new Task[C] { val f = task } | |
implicit def limitToContext(limit: String) = new UnitTestContext(dateFormat.parse(limit)) | |
import Specs._ | |
def main(args: Array[String]) { | |
// --- Test cases | |
(`開発環境を整える` << "2012/03/09")( | |
(`PCをインストールする` ~ `IDEをインストールする`) < "2012/01/07", | |
(`コーヒータイム`) < "2012/02/01", | |
(`ひたすら待つ`) < "2012/02/03", | |
(`開発環境を整える` << "2012/02/05")( | |
(`PCをインストールする` ~ `IDEをインストールする`) < "2012/02/07", | |
(`ひたすら待つ`) < "2012/03/03", | |
(`コーヒータイム` << "2012/03/04")( | |
(`コーヒータイム` ~ `ひたすら待つ`~ `コーヒータイム`) < "2012/03/05", | |
(`コーヒータイム`) < "2012/03/06", | |
(`ひたすら待つ`) < "2012/03/07" | |
) | |
) | |
) run ("2012/03/10") | |
} | |
} | |
object Specs { | |
val `開発環境を整える` = (bearer: Bearer[UnitTestContext]) => { | |
println("開発環境を整える: unitl " + bearer.context.limit + ", celler limit: " + bearer.celler.limit) | |
""" | |
未 | |
""" | |
bearer | |
} | |
val `PCをインストールする` = (bearer: Bearer[UnitTestContext]) => { | |
println("PCをインストールする: unitl " + bearer.context.limit + ", celler limit: " + bearer.celler.limit) | |
""" | |
未 | |
""" | |
bearer | |
} | |
val `IDEをインストールする` = (bearer: Bearer[UnitTestContext]) => { | |
println("IDEをインストールする: unitl " + bearer.context.limit + ", celler limit: " + bearer.celler.limit) | |
""" | |
未 | |
""" | |
bearer | |
} | |
val `ひたすら待つ` = (bearer: Bearer[UnitTestContext]) => { | |
println("ひたすら待つ: unitl " + bearer.context.limit + ", celler limit: " + bearer.celler.limit) | |
""" | |
未 | |
""" | |
bearer | |
} | |
val `コーヒータイム` = (bearer: Bearer[UnitTestContext]) => { | |
println("コーヒータイム: unitl " + bearer.context.limit + ", celler limit: " + bearer.celler.limit) | |
""" | |
未 | |
""" | |
bearer | |
} | |
} | |
// --- | |
class Bearer[C](val context: C, val celler: C) | |
trait Task[C] { | |
val f: Bearer[C] => Bearer[C] | |
def ~[A](g: Bearer[C] => A): Bearer[C] => A = f andThen g | |
def <(c: C) = new Tasks[C] { | |
val context = c | |
val task = Option(f) | |
val sub = Nil | |
} | |
def <<(c: C)(s: Tasks[C]*) = new Tasks[C] { | |
val context = c | |
val task = Option(f) | |
val sub = s.toList | |
} | |
} | |
trait Tasks[C] { | |
val context: C | |
val task: Option[Bearer[C] => Bearer[C]] | |
val sub: List[Tasks[C]] | |
final def run(c: C): Unit = { | |
var celler: C = c | |
task.foreach(_.apply(new Bearer(context, celler))) | |
celler = context | |
val s = new scala.collection.mutable.Queue[Tasks[C]] | |
s ++= sub | |
while (!s.isEmpty) { | |
val t = s.dequeue | |
t.task.foreach( | |
_.apply(new Bearer(t.context, celler)) | |
) | |
celler = t.context | |
s ++= (t.sub.flatMap { v => | |
v.task.foreach { vt => | |
vt.apply(new Bearer(v.context, celler)) | |
celler = v.context | |
} | |
v.sub | |
}) | |
} | |
} | |
} |
Task#untilAllの引数に可変長引数で渡してるけど、
(`PCをインストールする` ~ `IDEをインストールする`) until "2012/01/07",
(`ひたすら待つ`) until "2012/03/03"
カンマ区切りはカッコ悪いので、こんな感じのDSLにしたい。
(`PCをインストールする` ~ `IDEをインストールする`) until "2012/01/07" |
(`ひたすら待つ`) until "2012/03/03"
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tasks#runメソッドを末尾再帰最適化できない…誰か...