2009-12-18 4 views
0

Я хочу, чтобы иметь возможность изменять объект динамически, добавляя/удаляя свойства или методы «на лету». Чтобы добавить проблему, для удаления я подумал об использовании Set Meter Operator, но он ведет себя странно, насколько я могу видеть при удалении метода из объекта.Установить разницу между телом объекта и определением блока в Rebol

Например, если у меня есть

O: make object! [ 
    a: 1   
    f: func [][] 
    b: 1 
] 

Я могу вычитать [а: 1 б: 1] без проблем

>> difference third O [b: 1 a: 1] 
== [f: func [][]] 

Но я не могу вычесть е: FUNC [] []:

>> difference third O [f: func[][]] 
== [a: 1 b: func [][] func []] 
>> 

Выход странно (я кладу странно, может быть, это не звучит английский, как я не английский родной :))

Почему и что я должен делать вместо этого?

Спасибо.

+0

«Выход странный». Лучшая проблема. Когда-либо. – Skilldrick

+0

Вау - я не слышал упоминания о Реболе около 7 лет! – teabot

+0

Yeah Rebol Marketing отстой :) Но вы можете использовать Rebol для создания интересных материалов для других языков либо C#, Java, ...: http://reboltutorial.com/blog/create-your-own-dsl-for-java -or-c-part-4-add-a-semantic-layer/ –

ответ

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: Функция равенства основывается на идентичности

Две отдельные функции с са 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! - это возможность служить контекстом для привязки слов ...

+0

Спасибо, по вашему решению. Но чтобы вернуться к моему вопросу, хотя моя конечная цель - удалить, мой пример еще не включает удаление, я просто не понимаю, почему разница дает странный результат. –

+0

Хорошо, я обновил ответ, чтобы углубиться в это ... – HostileFork

0

Вы не можете динамически добавлять или удалять слова из объекта в Rebol 2. Если вы хотите имитировать это поведение, вам нужно создать и вернуть новый объект.

 Смежные вопросы

  • Нет связанных вопросов^_^