Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

[REBOL] Re: Hashes in Rebol

From: greggirwin:mindspring at: 9-Dec-2003 8:01

Hi Konstantin, KK> Why them are implemented in Rebol in such strange way? I think for consistency with other series types. REBOL's standard path notation is extremely convenient. KK> can I KK> 1. Remove <key, value> pair from hash KK> 2. Change value associated with the particular key
>> hash: make hash! []
== make hash! []
>> append hash [A 1 B 2 C 3 D 4]
== make hash! [A 1 B 2 C 3 D 4]
>> hash/b
== 2
>> hash/b: 22
== make hash! [A 1 B 22 C 3 D 4]
>> remove/part find hash 'b 2
== make hash! [C 3 D 4]
>> hash
== make hash! [A 1 C 3 D 4] You can also use intermediate words as variables, along with the get-word! syntax in the path to evaluate them
>> key: 'c
== c
>> hash/:key
== 3 But you can't set values that way.
>> hash/:key: 33
** Syntax Error: Invalid word -- :key: ** Near: (line 1) hash/:key: 33 You need to do something like the following:
>> head change next find hash key 33
== make hash! [A 1 C 33 D 4] Or write a little wrapper for that (no error handling in example!):
>> my-replace: func [series key value][change next find series key value] >> head my-replace hash 'd 44
== make hash! [A 1 C 33 D 44] Of course, you could make things work how you want, any number of ways. e.g. ; Keys don't *have* to be strings. ; If you assign a block to _data, it's up to you to make it a hash! if you want. dictionary: make object! [ ; Odd items are keys, even items are values. I.e. ; [key1 value1 key2 value2...] _data: make hash! [] clear: does [_data: make hash! []] count: does [(system/words/length? _data) / 2] length?: :count empty?: does [count = 0] keys: does [extract head _data 2] values: does [extract next head _data 2] item: func [key] [ if has-key? key [_data/:key] ] has-key?: func [key] [ found? find/skip _data key 2 ] remove: func [key] [ if has-key? key [system/words/remove/part find/skip _data key 2 2] ] change: func [key value] [ either has-key? key [_data/:key :value][append _data reduce [key :value]] ] contains?: func [value /only] [ either only [ found? find/skip/only next _data value 2 ][ found? find/skip next _data value 2 ] ] ] ;d: make dictionary [] ;d/_data: ["A" 1 "B" 2 "C" 3 "D" 4] ;d/change 0.0.0 "black" ;d/item 0.0.0 In your case that might be a good choice, but the main thing to look at for "normal" REBOL usage is how the model fits with standard REBOL idioms and style. REBOL is quite different from other languages, and sometimes trying to make it work like them will look good initially, because you're making it act in a familiar way. Sometimes, though, it will lead to inelegant solutions later because you just keep adding things, rather than stripping them away. The main thing to remember with REBOL is that everything is just data--a series of values--until it is evaluated. HTH! -- Gregg