为什么不能在 Rebol 中重写内置函数?
我创建了这个,
cloneset: :set
set: func[word [word!] value][
if/else (type? get word) = list! [
print "list is immutable"
][
cloneset word value
protect word
]
]
protect 'cloneset
protect 'set
在使用新的 set 函数定义 val 函数时出现此错误:
val: func[word [word!] value][
set word value
protect word
value
]
>> val: func[word [word!] value][
[ set word value
[ protect word
[ value
[ ]
** Script Error: set has no refinement called any
** Where: throw-on-error
** Near: if error? set/any 'blk try
我不明白为什么?
I have created this
cloneset: :set
set: func[word [word!] value][
if/else (type? get word) = list! [
print "list is immutable"
][
cloneset word value
protect word
]
]
protect 'cloneset
protect 'set
I have this error when defining the val function with the new set function:
val: func[word [word!] value][
set word value
protect word
value
]
>> val: func[word [word!] value][
[ set word value
[ protect word
[ value
[ ]
** Script Error: set has no refinement called any
** Where: throw-on-error
** Near: if error? set/any 'blk try
I don't understand why ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 Rebol 中,任何内置函数都可以被覆盖。 您实际上确实重写了上面的
set
函数。但是,当看到您获得的错误时,您应该检查
throw-on-error
函数。 您会发现,在函数源代码中,有一个对set
函数的调用,如下所示:该调用表明
throw-on-error
函数假设set
变量来引用具有/any
细化的函数。 由于您重新定义的函数版本没有这样的改进,因此 throw-on-error 函数无法以这种方式调用它,因此您会收到错误。一般来说,你可以重新定义任何东西,但你必须承担重新定义的责任,特别是如果重新定义的版本不能向后兼容原始版本。
In Rebol any built-in function can be overridden. You actually did override the
set
function above.However, when seeing the error you obtained you should have examined the
throw-on-error
function. You would have found out that in the function source code there is a call of theset
function looking as follows:This call suggests that the
throw-on-error
function assumes theset
variable to refer to a function having a/any
refinement. Since your redefined version of the function does not have such a refinement, thethrow-on-error
function cannot call it that way and thus the error you obtained.Generally spoken, you can redefine anything, but you have to take the responsibility for the redefinition, especially if the redefined version is not backwards compatible with the original.
当您重新定义在
system/words
中定义的单词时,您应该准确地重新定义它。set
一词有两个改进:/pad
和/any
,您的重新定义还应该包括:(我根本没有测试过上面的代码应该被视为伪代码。)
When you redefine a word that's defined in
system/words
, you should redefine it exactly. Theset
word has two refinements:/pad
and/any
that your redefinition should also include:(I have not tested the above code at all. It should be regarded as pseudocode.)
为了确保规范正确,您可以重用原始函数的规范:
在没有 'spec-of 的旧版本中,您可以使用 'first 代替它。
To be sure to get the spec right, you can reuse the spec of the original function:
in older versions without 'spec-of, you can use 'first in its place.