在Rebol中设置对象体和块定义之间的差异操作
我希望能够通过动态添加/删除属性或方法来动态修改对象。对于添加没有问题,对于删除,我考虑过使用设置差异数学运算符,但据我所知,当从对象中删除方法时,它的行为很奇怪。
例如,如果我有,
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 []]
>>
输出很奇怪(我说奇怪,也许它听起来不像英语,因为我不是英语为母语:))
为什么以及我应该做什么?
谢谢。
I want to be able to modify Object dynamically by adding / removing properties or methods on the fly. For Adding no problem, for Removing I thought about using Set Difference Math Operator but it behaves weirdly as far as I can see when removing a method from the object.
For example if I have
O: make object! [
a: 1
f: func [][]
b: 1
]
I can substract [a: 1 b: 1] with no problem
>> difference third O [b: 1 a: 1]
== [f: func [][]]
But I cannot substract f: func[][]:
>> difference third O [f: func[][]]
== [a: 1 b: func [][] func []]
>>
Output is weird (I put strange maybe it doesn't sound english as I'm not english native :) )
Why and what should I do instead ?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题#1:Difference 丢弃来自两个输入的重复项
首先,
difference
不应被视为“减法”运算符。它为您提供每个块中唯一的每个元素之一:因此,您可以通过与
[a: 1 b: 1]
和[1 a: b: 进行差分来获得等效集合: ]
。这就是最终输出中缺少第二个1
的原因。即使与空集进行差异也会删除任何重复的项目:如果您希望实际搜索并替换已知的顺序模式,那么您想要的更有可能
替换
为将您的替换作为空集:问题#2:函数相等基于同一性具有
相同定义的两个单独的函数将计算为两个不同的函数对象。例如,这两个函数都不带参数,也没有主体,但是当您使用
get-word!
获取它们并比较它们时,它们不相等:因此,奇怪结果中的另一个因素是
f:
将从集合中减去,并且两个(不同的)空函数是唯一的,因此都是差异集合的成员。R2 比 R3 有点奇怪,我无法让
:o/f
工作。但以下是一种获得您试图实现的差异的“人为正确外观版本”的方法:这里您使用的函数标识与您在要减去的块中放入的对象相同的函数标识。
在 R3 中,
difference
不支持这种方式的函数值。它可能与基于map!
的底层实现有关,它不能将“函数值”作为键。同样在 Rebol 3 中,在对象上使用差异是不合法的。所以即使你的第一个案例也行不通。 :(问题 #3:这不是添加和删除属性的方法
在 Rebol 3 中,您可以毫无问题地向对象动态添加属性。
但据我所知当然,一旦添加它们,您就无法将它们删除。当然,您可以将它们设置为“none”,但
如果您想尝试读取它们, 反射 API 仍会报告它们存在。抛出一个错误,您可以将其设置为一个错误对象,然后保护它们不被读取。这种方法的一种变体也适用于 R2:
R3 更进一步,让您可以保护成员不被写入,甚至隐藏成员不被读取。 。
如果您需要在 R2 中动态添加和删除成员,您还可以考虑对象中的数据成员,它是一个块。块和对象对于许多操作是可互换的,例如:
并且您可以从中删除内容 它们...
这完全取决于您的应用程序。
object!
超越block!
的主要功能是充当绑定单词的上下文...Issue #1: Difference Discards Duplicates From Both Inputs
Firstly,
difference
shouldn't be thought of as a "subtraction" operator. It gives you one of each element that is unique in each block:So you'd get an equivalent set by differencing with
[a: 1 b: 1]
and[1 a: b:]
. This is why the second1
is missing from your final output. Even differencing with the empty set will remove any duplicate items:If you're looking to actually search and replace a known sequential pattern, then what you want is more likely
replace
with your replacement as the empty set:Issue #2: Function Equality Is Based On Identity
Two separate functions with the same definition will evaluate to two distinct function objects. For instance, these two functions both take no parameters and have no body, but when you use a
get-word!
to fetch them and compare they are not equal:So another factor in your odd result is that
f:
is being subtracted out of the set, and the two (different) empty functions are unique and thus both members of the differenced set.R2 is a little weirder than R3 and I can't get
:o/f
to work. But the following is a way to get an ''artificially correct-looking version'' of the difference you are trying to achieve:Here you're using the same function identity that you put in the object in the block you are subtracting.
In R3,
difference
does not support function values in this way. It may relate to the underlying implementation being based onmap!
which cannot have ''function values'' as keys. Also in Rebol 3, using difference on an object is not legal. So even your first case won't work. :(Issue #3: This isn't how to add and remove properties
In Rebol 3 you can add properties to an object dynamically with no problems.
But as far as I know of, you cannot remove them once they have been added. You can set them to
none
of course, but the reflection APIs will still report them as being there.If you want to make trying to read them throw an error you can set it to an error object and then protect them from reads. A variant of this also works in R2:
R3 takes this one step further and lets you protect the member from writes, and even hide the member from having any new bindings made to it.
If you need to dynamically add and remove members in R2, you might also consider a data member in your object which is a block. Blocks and objects are interchangeable for many operations, e.g:
And you can remove things from them...
It all depends on your application. The main thing
object!
has going overblock!
is the ability to serve as a context for binding words...您无法在 Rebol 2 中动态添加或删除对象中的单词。如果您希望模拟此行为,您需要创建并返回一个新对象。
You cannot dynamically add or remove words from an object in Rebol 2. If you wish to simulate this behaviour you need to create and return a new object.