Reputation:
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 ?
Upvotes: 4
Views: 200
Reputation: 987
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 the set
function looking as follows:
set/any 'blk try ...
This call suggests that the throw-on-error
function assumes the set
variable to refer to a function having a /any
refinement. Since your redefined version of the function does not have such a refinement, the throw-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.
Upvotes: 3
Reputation: 521
To be sure to get the spec right, you can reuse the spec of the original function:
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]
in older versions without 'spec-of, you can use 'first in its place.
Upvotes: 3
Reputation: 16558
When you redefine a word that's defined in system/words
, you should redefine it exactly. The set
word has two refinements: /pad
and /any
that your redefinition should also include:
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.
}
]
]
(I have not tested the above code at all. It should be regarded as pseudocode.)
Upvotes: 6