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

How to remove words from objects?

 [1/13] from: luke:marmaladefoo at: 13-Jan-2004 10:21


Dear list I'm trying to dynamically add and remove words from an object. So far I can do the add words as follows:
>> obj: make object! [a: 1 b: 2] >> probe obj
make object! [ a: 1 b: 2 ]
>> obj: make obj [c: 3] >> probe obj
make object! [ a: 1 b: 2 c: 3 ]
>>
now I want to remove c from obj. How do I do that. I know I could dynamically reconstruct it from scratch, but that is not very elegant. There must be a better way to get back to obj being: make object! [a: 1 b: 2] Any ideas? Thanks - Luke __________________________________________ Various gadgets widgets, links and chat http://www.marmaladefoo.com __________________________________________<

 [2/13] from: carl:cybercraft at: 24-Jan-2004 11:49


On 13-Jan-04, Luke wrote:
> Dear list > I'm trying to dynamically add and remove words from an
<<quoted lines omitted: 19>>
> make object! [a: 1 b: 2] > Any ideas?
The third value in an object is its block. ie...
>> obj: make object! [a: 1 b: 2 c: 3] >> third obj
== [a: 1 b: 2 c: 3] So, you could make an object from a copy of that block with the values you don't want removed. The following for instance creates a new object from the above one with the last two values removed...
>> obj2: make object! head clear back back tail copy third obj >> probe obj
make object! [ a: 1 b: 2 c: 3 ]
>> probe obj2
make object! [ a: 1 b: 2 ] Not sure how it'd work for more complex objects though. -- Carl Read

 [3/13] from: luca::truffarelli::it at: 13-Jan-2004 12:02


Not so beautifull but maybe work: removefromobj: func [obj word] [ make object! head remove remove skip third obj add index? find first obj word -1 ] rr: make object! [ a: 1 b: 2 c: 3 ] probe removefromobj rr 'b

 [4/13] from: ingo:2b1 at: 13-Jan-2004 12:17


Hi Luke, Luke wrote:
> Dear list > I'm trying to dynamically add and remove words from an
<<quoted lines omitted: 15>>
>> obj: make object! remove/part find third obj to set-word! 'c 2 >> probe obj
make object! [ a: 1 b: 2 ] The main part in this expression is "third obj", which returns the object as a block, like this:
>> third obj
== [a: 1 b: 2] After that it boils down to removing the part that constructs the element you want to remove, and use the new block to construct your object. BUT BEWARE: you are always constructing NEW OBJECTS! This means, that references still point to the old object, e.g.
>> obj: make object! [a: 1 b: 2] >> a: []
== []
>> insert a obj
== []
>> probe a/1
make object! [ a: 1 b: 2 ]
>> obj: make obj [c: 3] >> probe obj
make object! [ a: 1 b: 2 c: 3 ]
>> probe a/1
make object! [ a: 1 b: 2 ] ; !!! a contains a reference to the old 'obj So, it works well if you have only well defined references to your objects, otherwise just use block!s for very dynamic entities. The downside is that lookup in a block is not as fast as in an object. I hope that helps, Ingo

 [5/13] from: joel:neely:fedex at: 13-Jan-2004 9:44


Hi, Luke, Sorry. Luke wrote:
> Dear list > > I'm trying to dynamically add and remove words from an > object... >
You can't.
> now I want to remove c from obj. How do I do that. I > know I could dynamically reconstruct it from scratch, but > that is not very elegant. There must be a better way to > get back to obj being: >
There's not. -jn- -- ---------------------------------------------------------------------- Joel Neely joelDOTneelyATfedexDOTcom 901-263-4446 Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1

 [6/13] from: greggirwin:mindspring at: 13-Jan-2004 10:50


Hi Luke, You already got some solutions; I'll just add some comments. L> I'm trying to dynamically add and remove words from an L> object...I know I could dynamically reconstruct it from scratch, L> but that is not very elegant. There must be a better way... Not really. The issue lies in the fact that the context of an object isn't dynamic; you can't add or remove things. The global context in REBOL is the only special case of a dynamic context I believe. You can get tricky and work around it, by including a block in your object and using that as kind of a sub-context--because blocks are resizable. I think Ladislav or Joel posted a dynamic object example here at one time. I didn't find one on REBOL.org in a quick search, maybe somebody submit one if they have it handy. -- Gregg

 [7/13] from: maximo:meteorstudios at: 13-Jan-2004 13:25


did you know you do not need a real object for object-like behaviour. This is not the solution to everything, but well used, it can be as effective. note that in the following, there is no context. and no 'self word. (you could define it, but I'll leave that little part as an exam. Actually, one solution is included later ;-) in short, just use a block which looks like the pairs of words and values you use to define objects, but don't use set-word (word:) just simple words (word) . blk: [ a 1 b 2 ]
>> blk/a
== 1
>> blk/b
== 2 you can also add functions to it although its a little more complicated, but their usage is as easy. blk: compose [ a 1 b 2 pr (func [arg1][print [arg1 "...done!"]]) ] note the use of compose and the outer parenthesis surrounding the function definition to use it though its as easy
>> blk/pr "hello world"
hello world ...done! you can also assign values to the block like you would with objects: blk/a: 44 when blocks are used for simple data storage, used properly, this trick makes blocks behave almost identically like objects. With the difference that you can edit them much more easily and that any references to them becomes safe. adding a new thing to the object: append blk [thing "thang"] probe blk [ a 1 b 2 pr (func [arg1][print [arg1 "...done!"]]) thing "thang" ] but again, remember that there is no context, so functions do have limits unless you really tear up your rebol mind and start doing run-time binding.. which is not the easier task... you can also add an argument to all functions called 'self, which then mimics the useage of self. I this case, when calling a function in the block, just supply the block as the first parameter of the function call... with the tone of your mail, it seems that you are rather new to rebol. if this is the case then Welcome!, and I hope this example is a true testatment to how rebol can be used in many different ways. Also note that rebol recycles most constructs you have learned, instead of forcing you to learn completely new constructs for each different task. for example, arguments, blocks of data, object specs code blocks, are all built up of BLOCK, which can be expressed as rebol encounters them. in other languages, these are all built up of different (similar) datatypes each allowing ONLY a (small?) subset of the capabilities which they all share. HTH! -MAx --- You can either be part of the problem or part of the solution, but in the end, being part of the problem is much more fun.

 [8/13] from: luke:marmaladefoo at: 13-Jan-2004 18:25


Dear all thanks everyone for your contributions! I have in the meantime implemented my own approach which works for me (similar to the ones suggested - see below) using the "long way round" of reconstructing the object. Its not very pretty (since it involves a "do" on a dynamically built string) but it works for me, as do most of your helpful suggestions. I dont understand Gregg what you mean when you say the context of an object isnt dynamic. It probably goes beyond my current level of understanding of how REBOL works. But if so, then how does that explain why can I do this (but not reverse the action): ;---create object obj: make object [a: 1] ;---add a new word to the object obj: make obj [b: 2]
> L> I'm trying to dynamically add and remove words from an > L> object...I know I could dynamically reconstruct it from scratch,
<<quoted lines omitted: 7>>
> here at one time. I didn't find one on REBOL.org in a quick search, > maybe somebody submit one if they have it handy.
This is the way I did it: object-remove-word: func [object word /local obj-result obj-copy-string action] [ obj-copy-string: copy "" obj-result: none foreach w next first object [ if not (w = word) [ value: object/:w append obj-copy-string rejoin [ " " :w ": " mold :value newline ] ] ] action: rejoin ["make object! [" obj-copy-string "]" ] obj-result: do action :obj-result ] All the best - Luke __________________________________________ Various gadgets widgets, links and chat http://www.marmaladefoo.com __________________________________________<

 [9/13] from: ammon:addept:ws at: 13-Jan-2004 12:20


Luke to extend an object, MAKE the object...
>> obj: make object! [a: 'a] >> obj: make obj [b: 'b] >> probe obj
make object! [ a: 'a b: 'b ] HTH! ~~Ammon ;->

 [10/13] from: joel:neely:fedex at: 13-Jan-2004 13:54


Hi, Luke, Luke wrote:
> I dont understand Gregg what you mean when you say > the context of an object isnt dynamic... >
Once an object has been created, its "context" (namespace) is set in concrete and cannot be changed (although the values to which its words are set *can* be changed).
> But if so, then how does that explain why can I do this > (but not reverse the action): > > ;---create object > obj: make object [a: 1] > > ;---add a new word to the object > obj: make obj [b: 2] >
Because you are not adding a new word to *the*original* object, but instead are creating a *new* object (based on the original) which contains the new value. To see that this is not modifying the original, just consider this:
>> obj: make object! [a: 1] >> other: obj >> obj: make obj [b: 2] >> source obj
obj: make object! [ a: 1 b: 2 ]
>> source other
other: make object! [ a: 1 ] So the original object is still around (referent of OTHER) but now OBJ refers to a *new* object.
>> >>You can get tricky and work around it, by including a block in your >>object and using that as kind of a sub-context--because blocks are >>resizable. I think Ladislav or Joel posted a dynamic object example >>here at one time... >>
If you want shared references to an object to all show the effect of such "structural" changes, you can wrap the object in another object (i.e. create an additional level of indirection) which is the common referent:
>> wrapper: make object! [
[ inner: make object! [ [ a: 1 [ ] [ ]
>> obj: wrapper >> other: wrapper >> source obj
obj: make object! [ inner: make object! [ a: 1 ] ]
>> source other
other: make object! [ inner: make object! [ a: 1 ] ]
>> obj/inner: make obj/inner [b: 2] >> source obj
obj: make object! [ inner: make object! [ a: 1 b: 2 ] ]
>> source other
other: make object! [ inner: make object! [ a: 1 b: 2 ] ] (Of course, the wrapper could be a block as well, but using an object as a wrapper allows an easy way to put methods in the wrapper that delegate to the inner object, so you can hide the indirection from any client code.) -jn- -- Joel Neely com dot fedex at neely dot joel I had proved the hypothesis with a lovely Gedankenexperiment, but my brain was too small to contain it. -- Language Hat

 [11/13] from: greggirwin:mindspring at: 13-Jan-2004 13:41


Hi Luke, L> I dont understand Gregg what you mean when you say L> the context of an object isnt dynamic. It probably goes L> beyond my current level of understanding of how REBOL L> works. It just means that once you create an object, you can't add or remove words from its context (words bound to the object); it's a fixed size. You have to create a new object, which then has its own fixed size context to add or remove words. L> But if so, then how does that explain why can I do this L> (but not reverse the action): L> ;---create object L> obj: make object [a: 1] L> ;---add a new word to the object L> obj: make obj [b: 2] This works because you're making a new object. After it's made, all you can do is change the values that its words refer to, you can't unbind and remove the words themselves. To do that, you need to create a new object that just doesn't contain them. L> object-remove-word: func [object word /local ... Does this work for you? remove-word: func [object word] [ make object! head remove/part find third object to set-word! word 2 ] It's dense code, I know. Here's how the calls relate: make object! head remove/part find third object to set-word! word 2 It will fail with an error if the word doesn't exist in the object. Just FYI. -- Gregg

 [12/13] from: g:santilli:tiscalinet:it at: 14-Jan-2004 9:50


Hi Gregg, On Tuesday, January 13, 2004, 9:41:35 PM, you wrote: GI> remove-word: func [object word] [ GI> make object! head remove/part find third object to set-word! word 2 GI> ] BTW, on newer version of REBOL, if you're making the object from the THIRD of another object, you should use CONSTRUCT. On earlier versions of REBOL, where CONSTRUCT is not available, you'd either have to write something like CONSTRUCT, or you need to keep in mind that the above does not work on all objects. This is a problematic example for the above:
>> print mold third context [a: 'a]
[a: a] Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/

 [13/13] from: greggirwin:mindspring at: 14-Jan-2004 11:39


Hi Gabriele, GS> BTW, on newer version of REBOL, if you're making the object from GS> the THIRD of another object, you should use CONSTRUCT. Excellent point! -- Gregg

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted