2009-12-18 50 views
0

我希望能夠動態地通過添加/刪除屬性或方法來動態修改對象。對於添加沒有問題,對於刪除我想過使用Set Difference Math Operator,但是從我看到的從對象中移除一個方法時,它的表現很奇怪。在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 []] 
>> 

輸出很奇怪(我把奇怪也許它不會英語,因爲我不是英國原生:))

爲什麼,我該怎麼做呢?

謝謝。

+0

「輸出很奇怪。」最好的問題。永遠。 – Skilldrick 2009-12-18 14:39:07

+0

哇 - 我沒有聽說過Rebol約7年! – teabot 2009-12-18 14:40:49

+0

是的Rebol營銷爛:)但你可以使用Rebol做其他語言的有趣的東西要麼C#,Java,...: http://reboltutorial.com/blog/create-your-own-dsl-for-java -or-c-part-4-adding-a-semantic-layer/ – 2009-12-18 21:08:17

回答

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:功能平等是一種基於身份與sa

兩個單獨的功能我的定義將評估爲兩個不同的功能對象。舉例來說,這兩個功能都沒有參數,沒有身體,但是當你使用一個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:這不是如何添加和刪除屬性

在雷博爾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中,您也可以考慮在你的對象,它是一個塊的數據成員。塊和對象是可互換的許多操作,e.g:

>> 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

謝謝,會在你的解決方案。但回到我的問題,雖然我的最終目的是要刪除,但我的例子並不涉及刪除,我只是不明白爲什麼差異給出了一個奇怪的結果。 – 2010-01-04 15:11:05

+0

好的,我已經更新了答案,深入瞭解了一些... – HostileFork 2010-01-04 17:38:46

0

您無法動態地添加或刪除Rebol 2中的對象中的單詞。如果您希望模擬此行爲,則需要創建並返回一個新對象。

相關問題