[squeak-dev] versioning objects

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] versioning objects

Jimmie Houchin-3
Hello,

I am writing a web app and I need to version the attributes of my
objects so that I can enable undo capabilities.

Is there a best practices way to offer such?

Currently I am implementing accessors which simply create an
OrderedCollection for each attribute.


id: anObject
    id ifNil: [
        id := OrderedCollection new.
        id add: anObject].
    (id = anObject) ifFalse: [id add: anObject]

 
obj id
    ^ id last


Is there a more standard or better way to offer such features?

Any wisdom greatly appreciated.

Jimmie

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] versioning objects

Janko Mivšek
Hi Jimmie,

In Aida/Web you have quite some support for versioning. See Aida-Support
  category and VersionedObject with VersionSpec. For instance
VersionedObject is used in Aida/Scribo for versioning content (wiki
pages etc.).

JAnko

Jimmie Houchin wrote:

> Hello,
>
> I am writing a web app and I need to version the attributes of my
> objects so that I can enable undo capabilities.
>
> Is there a best practices way to offer such?
>
> Currently I am implementing accessors which simply create an
> OrderedCollection for each attribute.
>
>
> id: anObject
>     id ifNil: [
>         id := OrderedCollection new.
>         id add: anObject].
>     (id = anObject) ifFalse: [id add: anObject]
>
>  
> obj id
>     ^ id last
>
>
> Is there a more standard or better way to offer such features?
>
> Any wisdom greatly appreciated.
>
> Jimmie
>
>

--
Janko Mivšek
AIDA/Web
Smalltalk Web Application Server
http://www.aidaweb.si

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] versioning objects

Colin Putney
In reply to this post by Jimmie Houchin-3

On 15-Apr-08, at 3:15 PM, Jimmie Houchin wrote:

> Currently I am implementing accessors which simply create an
> OrderedCollection for each attribute.
>
>
> id: anObject
>    id ifNil: [
>        id := OrderedCollection new.
>        id add: anObject].
>    (id = anObject) ifFalse: [id add: anObject]
>
>
> obj id
>    ^ id last
>
>
> Is there a more standard or better way to offer such features?

I think an important thing to consider is the unit of work that will  
be undoable. If it's "revert #id of <some object> to the previous  
value" then your ordered collection scheme is probably not bad. But if  
there are more complex actions that need to be undo, this kind of  
thing will be difficult.

The usual way to do this is to have all your undoable units of work be  
implemented by "command" objects that know how to perform a specific  
action. Then when the user does something undoable, you create a  
command, execute it, then push it on the undo stack. To undo you can  
either have the command know how to undo its self, or have it create  
an "inverse" command. This kind of thing works pretty well, and it can  
be extended with other features like redo, logging, journal-and-
snapshot persistence etc.

Hope this helps,

Colin

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] versioning objects

timrowledge

On 15-Apr-08, at 8:46 PM, Colin Putney wrote:

>
>
> The usual way to do this is to have all your undoable units of work  
> be implemented by "command" objects that know how to perform a  
> specific action. Then when the user does something undoable, you  
> create a command, execute it, then push it on the undo stack. To  
> undo you can either have the command know how to undo its self, or  
> have it create an "inverse" command. This kind of thing works pretty  
> well, and it can be extended with other features like redo, logging,  
> journal-and-snapshot persistence etc.
That's pretty much what we did in Sophie. It's non-trivial but then  
the problem domain is non-trivial.

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
A sad tale that brings a lump to the eye and a tear to the throat.



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] versioning objects

Jimmie Houchin-3
In reply to this post by Janko Mivšek
Janko Mivšek wrote:
> Hi Jimmie,
>
> In Aida/Web you have quite some support for versioning. See Aida-Support
>  category and VersionedObject with VersionSpec. For instance
> VersionedObject is used in Aida/Scribo for versioning content (wiki
> pages etc.).
>
> JAnko

Thanks Janko, I'll look into that.

Jimmie

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] versioning objects

Jimmie Houchin-3
In reply to this post by Colin Putney
Colin Putney wrote:

>
> On 15-Apr-08, at 3:15 PM, Jimmie Houchin wrote:
>
>> Currently I am implementing accessors which simply create an
>> OrderedCollection for each attribute.
>>
>>
>> id: anObject
>>    id ifNil: [
>>        id := OrderedCollection new.
>>        id add: anObject].
>>    (id = anObject) ifFalse: [id add: anObject]
>>
>>
>> obj id
>>    ^ id last
>>
>>
>> Is there a more standard or better way to offer such features?
>
> I think an important thing to consider is the unit of work that will be
> undoable. If it's "revert #id of <some object> to the previous value"
> then your ordered collection scheme is probably not bad. But if there
> are more complex actions that need to be undo, this kind of thing will
> be difficult.
>
> The usual way to do this is to have all your undoable units of work be
> implemented by "command" objects that know how to perform a specific
> action. Then when the user does something undoable, you create a
> command, execute it, then push it on the undo stack. To undo you can
> either have the command know how to undo its self, or have it create an
> "inverse" command. This kind of thing works pretty well, and it can be
> extended with other features like redo, logging, journal-and-snapshot
> persistence etc.
>
> Hope this helps,

Thanks Colin (and Tim).

I'll have to study that and learn how to do that. Right now I have a
vague understanding of what you are saying, But it will require some
thought before I can proceed implementing such.

Currently I went forward with accessors for all of my attributes like I
wrote above. That will give me a history of the attribute which I can
display to the user for them to be able to manipulate.

Again thanks for something to explore and learn about and possibly use
in a future iteration.

Jimmie

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] versioning objects

Michael Davies-2
In reply to this post by Colin Putney
On Wed, Apr 16, 2008 at 4:46 AM, Colin Putney <[hidden email]> wrote:
...
>  The usual way to do this is to have all your undoable units of work be
> implemented by "command" objects that know how to perform a specific action.
> Then when the user does something undoable, you create a command, execute
> it, then push it on the undo stack. To undo you can either have the command
> know how to undo its self, or have it create an "inverse" command. This kind
> of thing works pretty well, and it can be extended with other features like
> redo, logging, journal-and-snapshot persistence etc.
>
Jimmy, if you're looking for a relatively simple solution, Apple's
NSUndoManager is a very simple implementation of this idea, though it
does require the programmer to explicitly define the action that will
re-create current state, but it's very easy to implement if it meets
your needs.
(See http://dotnetaddict.dotnetdevelopersjournal.com/nsundomanager.htm
for a fuller description).

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] versioning objects

hernan.wilkinson
In reply to this post by Colin Putney
We did something similar with our financial application, therefore all financial transactions can be canceled and all their impact (from registration to accounting) can be undone.
You can read a little bit about this in the Command pattern documented in the GOF

Bye,
Hernan.

On Wed, Apr 16, 2008 at 1:06 AM, tim Rowledge <[hidden email]> wrote:

On 15-Apr-08, at 8:46 PM, Colin Putney wrote:


The usual way to do this is to have all your undoable units of work be implemented by "command" objects that know how to perform a specific action. Then when the user does something undoable, you create a command, execute it, then push it on the undo stack. To undo you can either have the command know how to undo its self, or have it create an "inverse" command. This kind of thing works pretty well, and it can be extended with other features like redo, logging, journal-and-snapshot persistence etc.
That's pretty much what we did in Sophie. It's non-trivial but then the problem domain is non-trivial.

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
A sad tale that brings a lump to the eye and a tear to the throat.