【发布时间】:2017-04-10 00:42:07
【问题描述】:
在 JS 中,我可以通过 arguments 对象访问函数参数。
我想在 ScalaJS 中以某种方式做同样的事情,因为我想为函数和它们得到的参数做一些日志记录。
有可能吗?
【问题讨论】:
-
请用您正在尝试做的事情的 sn-p 更新您的问题。目前形式的问题很难理解。
标签: scala.js
在 JS 中,我可以通过 arguments 对象访问函数参数。
我想在 ScalaJS 中以某种方式做同样的事情,因为我想为函数和它们得到的参数做一些日志记录。
有可能吗?
【问题讨论】:
标签: scala.js
嗯——有趣的问题。老实说,我不知道是否有办法访问arguments 本身。我可能会通过使用 sourcecode library 来解决记录函数参数的愿望,它是为这类事情设计的,但我承认我还没有从 Scala.js 尝试过......
【讨论】:
您不能直接访问 Scala.js 中的 arguments 对象。但是,您可以使用可变参数导出方法,它会在 JavaScript 中按预期工作:
object Logger {
@JSExportTopLevel("log")
def log(xs: js.Any*): Unit = {
xs.foreach(println)
}
}
这定义并将log 导出到顶级范围。在 JavaScript 代码中,您现在可以调用:
log(1, {}, {a: 1}, "foo");
【讨论】:
xs基本上和arguments对象是一回事。你可以把那个传过去。
arguments 让我可以访问所有函数参数。问题不在于日志记录,而在于传递参数。我可以有一个带有 1 参数的函数,另一个带有 3 的函数,并且我需要使用这些相同的参数调用 log()。但是,如果我可以访问arguments,我就可以通过log(arguments)。
trace("functionName", arguments),这样你就会得到一个“呼叫日志”。我猜在 Scala 中,只有使用隐式或宏元编程才有可能。
正如@justin-du-coeur 建议的那样,您可以为此使用sourcecode。例如:
object Test extends js.JSApp {
def main(): Unit = {
a(1, "a")
b()
c("foo", "bar", "baz")
}
def trace()(implicit name: sourcecode.Name, args: sourcecode.Args): Unit = {
def makeArgList(as: Seq[sourcecode.Text[_]]): String =
as.map(a => f"${a.source} = ${a.value}").mkString("(", ", ", ")")
val argStr = args.value.map(makeArgList).mkString("")
println(f"${name.value}$argStr")
}
def a(arg1: Int, arg2: String): Unit = {
trace()
}
def b(): Unit = {
trace()
}
def c(x: String*): Unit = {
trace()
}
}
输出如下:
[info] Running Test
a(arg1 = 1, arg2 = a)
b()
c(x = WrappedArray(foo, bar, baz))
如您所见,trace 可以从上下文中捕获它需要的所有内容,因此结果比我能想到的任何 JS 解决方案都更加免费。
【讨论】: