我创建了这个
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
我不明白为什么?
答案 0 :(得分:6)
当您重新定义system/words
中定义的单词时,您应该重新定义正好。 set
字有两个改进:/pad
和/any
,您的重新定义也应包括:
cloneset: :set
set: func [
word [word! block!]
value
/any
/pad
][
either all [word? word list? get word] [
throw make error! "List is immutable!"
][
comment {
At this point you'll have to forward the arguments and refinements
of your SET method to CLONESET. This will be made much easier in R3
with the new APPLY function.
}
]
]
(我根本没有测试过上面的代码。它应该被视为伪代码。)
答案 1 :(得分:3)
为了确保规范正确,您可以重复使用原始功能的规范:
set: func spec-of :cloneset [
'new-implementation
]
source set
set: func [
{Sets a word, block of words, or object to specified value(s).}
word [any-word! block! object!] "Word or words to set"
value [any-type!] "Value or block of values"
/any "Allows setting words to any value."
/pad {For objects, if block is too short, remaining words are set to NONE.}
]['new-implementation]
在没有'spec-of的旧版本中,您可以首先使用'。
答案 2 :(得分:3)
在Rebol中,可以覆盖任何内置函数。你确实覆盖了上面的set
函数。
但是,当您看到您获得的错误时,您应该检查throw-on-error
函数。你会发现在函数源代码中有一个set
函数的调用,如下所示:
set/any 'blk try ...
此调用表明throw-on-error
函数假定set
变量引用具有/any
细化的函数。由于您重新定义的函数版本没有这样的细化,throw-on-error
函数无法以这种方式调用它,从而导致您获得错误。
一般来说,您可以重新定义任何内容,但您必须负责重新定义,特别是如果重新定义的版本不与原始版本向后兼容。