【发布时间】:2019-05-09 18:15:27
【问题描述】:
我试图在一个点拦截对我的库的所有调用,并在我的库函数之间共享一个自定义调用堆栈(一个数组)。
这是一个FP 库,其中管道/组合大量函数是一种常见做法。内置调用堆栈将跟踪所有调用(包含噪声),而我想忽略内部调用,只记录用户对库的调用并按照我的自定义堆栈手动管理内部调用的跟踪。似乎解决方案的一部分是 apply 陷阱,但不知道从哪里开始。
// Ramda FP library
// Abbreviate input string: 'some input' -> 'S.I'
const app = R.pipe(R.w, R.x, R.y, R.z)
const output = app('some input')
// Sample actual call stack (including internal calls):
// w -> __w0 -> _t2 -> x -> _x1 -> _x2 -> y -> _y -> z -> _z9
// Desired call stack without internal calls (noise)
// x -> y -> z
如果我的库中有自己的调用堆栈数据结构,则可以生成上述示例的以下输出:
pipe: w -> x -> y -> z
'some input' ['s','i'] ['S','I'] 'S.I'
如果出现错误:
const output = app('')
// desired output
pipe: w -> x -> y -> z
'' [] Error
Error: Array is empty!
总结:我需要实现自己的虚拟调用栈,它很智能,用于为图书馆用户提供有用的数据。考虑到在 FP 库 currying 中,部分应用程序......是常见的用例,这使得问题更难解决。
【问题讨论】:
-
您应该包括一个示例使用和预期输出。
-
@user633183:添加了所需的输出。
-
即使假设您可以以某种方式修改调用堆栈,我认为您实际上无法做到这一点,因为单个回溯可能在您的库中有多个入口点。截断所有这些信息会丢失很多信息。代理也不能被 polyfill,所以如果你走那条路,你只会将自己限制在现代浏览器中。这有点像将 FP 习语移植到一种并非真正适合它们的语言上所付出的代价。
-
虽然我不知道有没有很好的解决方案,但您能否总结一下您用来为每个函数添加一些
skipStacktrace符号的库代码?这可能允许您以某种方式编写自己的堆栈跟踪函数。我真的不确定细节,但至少看起来是合理的。 -
@JaredSmith:你认为 OOP 习语更接近 JS 的核心吗?或者是其他东西?我想说该语言具有 FP 的许多重要功能:一流的高阶函数、闭包等。当然,不变性更难,但我想说它非常接近于哪种范式 JS 更适合。
标签: javascript proxy functional-programming ramda.js