我希望能够通过动态添加/删除属性或方法来动态修改Object。对于添加没有问题,对于删除我想到使用设置差异数学运算符,但它从我从对象中删除方法时可以看到奇怪的行为。
例如,如果我有
O: make object! [
a: 1
f: func [][]
b: 1
]
我可以毫无问题地减去[a:1 b:1]
>> difference third O [b: 1 a: 1]
== [f: func [][]]
但我无法减去f:func [] []:
>> difference third O [f: func[][]]
== [a: 1 b: func [][] func []]
>>
输出很奇怪(我把它说得很奇怪,因为我不是英国人,所以听起来不是英语:))
为什么以及我该怎么做呢?
感谢。
答案 0 :(得分:0)
您无法在Rebol 2中动态添加或删除对象中的单词。如果您希望模拟此行为,则需要创建并返回一个新对象。
答案 1 :(得分:0)
问题#1:差异丢弃两个输入的重复
首先,difference
不应被视为“减法”运算符。它为您提供每个块中唯一的每个元素之一:
>> difference [1 1 2 2] [2 2 2 3 3 3]
== [1 3]
>> difference [2 2 2 3 3 3] [1 1 2 2]
== [3 1]
因此,您可以通过与[a: 1 b: 1]
和[1 a: b:]
进行差异来获得等效集。这就是您的最终输出中缺少第二个1
的原因。即使使用空集进行差异也会删除任何重复项:
>> difference [a: 1 b: 1] []
== [a: 1 b:]
如果您希望实际搜索并替换已知的顺序模式,那么您更想要的是replace
替换为空集:
>> replace [a: 1 b: 1] [b: 1] []
== [a: 1]
问题#2:功能平等基于身份
具有相同定义的两个单独函数将评估为两个不同的函数对象。例如,这两个函数都没有参数且没有正文,但是当你使用get-word!
来获取它们并进行比较它们不相等时:
>> foo: func [] []
>> bar: func [] []
>> :foo == :bar
== false
因此,奇怪结果中的另一个因素是f:
被从集合中减去,并且两个(不同的)空函数是唯一的,因此是差集的两个成员。
R2比R3更怪异,我不能让:o/f
工作。但是以下是一种方法来获得你想要实现的差异的“人工正确版本”:
>> foo: func [] []
>> o: make object! [a: 1 f: :foo b: 2]
>> difference third o compose [f: (:foo)]
== [a: 1 b: 2]
在这里,您使用的是与您正在减去的块中的对象相同的函数标识。
在R3中,difference
不支持这种方式的函数值。它可能与基于map!
的底层实现有关,它不能将“函数值”作为键。同样在Rebol 3中,使用对象的差异是不合法的。所以即使你的第一个案例也行不通。 :(
问题#3:这不是添加和删除属性的方法
在Rebol 3中,您可以动态地向对象添加属性而不会出现任何问题。
>> obj: object [a: 1]
== make object! [
a: 1
]
>> append obj [b: 2]
== make object! [
a: 1
b: 2
]
但据我所知,一旦添加它们就无法删除它们。当然,您可以将它们设置为none
,但反射API仍会将它们报告为存在。
如果您想尝试阅读它们会抛出错误,您可以将其设置为错误对象,然后保护它们不被读取。其中一个变体也适用于R2:
>> attempt [obj/b: to-error "invalid member"]
== none
>> probe obj
== make object! [
a: 1
b: make error! [
code: 800
type: 'User
id: 'message
arg1: "invalid member"
arg2: none
arg3: none
near: none
where: none
]
]
>> obj/b
** User error: "invalid member"
R3更进一步,让您保护成员免受写入,甚至隐藏成员不会对其进行任何新绑定。
>> protect 'obj/b
== obj/b
>> obj/b: 100
** Script error: protected variable - cannot modify: b
>> protect/hide 'obj/b
== obj/b
>> obj
== make object! [
a: 1
]
如果需要在R2中动态添加和删除成员,您可能还会考虑对象中的数据成员是块。块和对象可以在许多操作中互换,例如:
>> data: [a: 1 b: 2]
== [a: 1 b: 2]
>> data/a
== 1
>> data/b
== 2
你可以从中删除东西......
>> remove/part (find data (to-set-word 'a)) 2
== [b: 2]
这完全取决于您的申请。 object!
的主要内容是block!
,它可以作为绑定词语的上下文......