Выпуск № 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: Функция равенства основывается на идентичности
Две отдельные функции с са me определение будет оцениваться двумя различными объектами функции. Например, эти две функций и не принимают никаких параметров и не имеют тела, но когда вы используете 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!
- это возможность служить контекстом для привязки слов ...
«Выход странный». Лучшая проблема. Когда-либо. – Skilldrick
Вау - я не слышал упоминания о Реболе около 7 лет! – teabot
Yeah Rebol Marketing отстой :) Но вы можете использовать Rebol для создания интересных материалов для других языков либо C#, Java, ...: http://reboltutorial.com/blog/create-your-own-dsl-for-java -or-c-part-4-add-a-semantic-layer/ –