gpt4 book ai didi

scala - 如何在 Scala 中使用最少的额外样板为命令行创建 DSL

转载 作者:行者123 更新时间:2023-12-04 05:25:33 25 4
gpt4 key购买 nike

我需要为不熟悉 scala(既不是 Java)但熟悉 Shell 的用户开发 API。他们基本上会在 scala 类中编写 shell 脚本(我知道我可以只调用外部 shell 脚本,但是来吧!此外,稍后我们将有一些用于常见 shell 任务的函数)。

我希望完成类似的事情:

1 object MyCoolScript extends MyMagicTrait {
2 $ "mkdir /tmp/test"
3 $ "cd /tmp/test"
4 $ "wget some-url"
5 }

更直接的是,如何将第 2-4 行(或可能不太简洁的版本)转换为可以在 MyMagicTrait 中处理的 Seq[String] ?

我知道 sys.process.stringToProcess 但如果我有:
object MyCoolScript extends MyMagicTrait {
"mkdir /tmp/test" !!
"cd /tmp/test" !!
"wget some-url" !!
}

如何以简洁的方式获取每个命令的结果?另外,我希望有一个 $"xxx"符号。

发布答案更新:

感谢@debilski、@tenshi 和@daniel-c-sobral,我能够非常接近所需的实现: https://gist.github.com/2777994

最佳答案

似乎 Scala 2.10 附带的字符串插值可以帮助您。首先你可以实现简单的$方法,它只是立即执行命令。为了做到这一点,你需要在 StringContext 上添加这个自定义方法。 :

object ShellSupport {
implicit class ShellStrings(sc: StringContext) {
def $(args: Any*) =
sc.s(args: _*) split "\n" map (_.trim) filterNot (_.isEmpty) foreach { cmd =>
// your excution logic goes here
println(s"Executing: $cmd")
}

}
}

现在你可以像这样使用它:
import ShellSupport._

val testDir = "/tmp/test"

$"mkdir $testDir"
$"cd $testDir"
$"""
wget some-url
wget another-url
"""

您可以利用它的语法(它唯一的缺点是不能在 $" 之间添加空格)和命令中的字符串插值。

现在让我们尝试实现您的魔法特性。这通常是相同的想法,但我也在使用 DelayedInit以便正确定义命令,然后在类创建期间自动执行它们。
trait MyMagicTrait extends DelayedInit {
private var cmds: List[String] = Nil

def commands = cmds

implicit class ShellStrings(sc: StringContext) {
def $(args: Any*) = {
val newCmds = sc.s(args: _*) split "\n" map (_.trim) filterNot (_.isEmpty)
cmds = cmds ++ newCmds
}
}

def delayedInit(x: => Unit) {
// your excution logic goes here
x
cmds map ("Excutintg: " + _) foreach println
}
}

它的用法是:
class MyCoolScript extends MyMagicTrait {
val downloader = "wget"

$"mkdir /tmp/test"
$"cd /tmp/test"
$"""
$downloader some-url
$downloader another-url
"""
}

new MyCoolScript

这两种解决方案产生相同的输出:
Executing: mkdir /tmp/test
Executing: cd /tmp/test
Executing: wget some-url
Executing: wget another-url

关于scala - 如何在 Scala 中使用最少的额外样板为命令行创建 DSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10708136/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com