Dear XOTcl/NX/NSF community,
I am in the process of upgrading one of our OpenACS based systems to XOTcl 2 and stumbled over the following legacy code:
Class create Person -slots { foreach e {username first_names last_name email etcetera} { Attribute $e -default "" -proc assign {o var value} {$o changed_var $var $value} } }
Person ad_instproc -private changed_var {var value} {} { my instvar __changed_vars lappend __changed_vars $var my instvar $var set $var $value }
The intention of this not-so-pretty code mainly seems to be that the Person->save method called by code like the following can recognize which attributes have actually changed during the last request, and update the database accordingly...
Person john john last_name doe john save
For some reason, now that I have upgraded the system to XOTcl 2, this does not work anymore. The list __changed_vars is not updated (in the example above, it would not contain last_name; for debugging purposes, I have put a log statement into the "assign" proc, it seems that it does not get called.)
As the update process introduced many many other changes as well (compared to the old and adapted OpenACS we had there), including changes in xotcl-core, it could certainly be the case that this is simply a the side-effect of some other change / or messed-up merge. So, my question is, SHOULD this work anyway in the latest stable version of XOTcl 2, or did the interface change?
Thanks for your help, Michael :-)
Dear Michael,
most of the advanced slot features of XOTcl 1 were marked as "experimental", which means, there is no guarantee, that this code will work in future releases.
Below is something, which probably close enough to the legacy code. The code enforces the creation of forwarder methods by using "-incremental 1". The multiplicity is set to 0..1 to be able to set attributes to "" (default, later values)
xotcl::Class create Person -slots { foreach e {username first_names last_name email etcetera} { Attribute $e -default "" -multiplicity 0..1 -incremental 1 $e proc value=set {o var value} { $o changed_var $var $value ${:default} } } } Person instproc changed_var {var value default} { if {$value ne $default} {lappend :__changed_vars $var} set :$var $value }
Appending the variable names like in the legacy code is probably not a good idea, since this means that when an attribute is set ten times, then the variable name is listed also 10 times. I fail also to understand, how the code detected changes from the database. It is initializing all attributes with "", which are probably not the database values. Somewhere the attributes must be properly initialized with the database values (and __changed_vars should be reset), but what happens with concurrent database updates? What should happen, when someone sets the attribute first to a different value and then to default?
So i guess, the legacy-code was just a rough indicator for purposes like "what attributes have non-default values", and for that purpose, the code above should be useful as a start
Some background: Much of nx went from the purely method-based attribute setters of XOTcl towards tk-like configure options. In XOTcl it is very dangerous to have e.g. an attribute named "set", for which an accessor method named "set" is generated, which will certainly conflict with the predefined method "set". nx does not have this problem, by using e.g. "... configure -set {...} ..."
best regards -gn
Am 12.10.15 um 17:10 schrieb Michael Aram:
Dear XOTcl/NX/NSF community,
I am in the process of upgrading one of our OpenACS based systems to XOTcl 2 and stumbled over the following legacy code:
Class create Person -slots { foreach e {username first_names last_name email etcetera} { Attribute $e -default "" -proc assign {o var value} {$o changed_var $var $value} } }
Person ad_instproc -private changed_var {var value} {} { my instvar __changed_vars lappend __changed_vars $var my instvar $var set $var $value }
The intention of this not-so-pretty code mainly seems to be that the Person->save method called by code like the following can recognize which attributes have actually changed during the last request, and update the database accordingly...
Person john john last_name doe john save
For some reason, now that I have upgraded the system to XOTcl 2, this does not work anymore. The list __changed_vars is not updated (in the example above, it would not contain last_name; for debugging purposes, I have put a log statement into the "assign" proc, it seems that it does not get called.)
As the update process introduced many many other changes as well (compared to the old and adapted OpenACS we had there), including changes in xotcl-core, it could certainly be the case that this is simply a the side-effect of some other change / or messed-up merge. So, my question is, SHOULD this work anyway in the latest stable version of XOTcl 2, or did the interface change?
Thanks for your help, Michael :-) _______________________________________________ Xotcl mailing list Xotcl@alice.wu-wien.ac.at http://alice.wu-wien.ac.at/mailman/listinfo/xotcl
...in response to " http://alice.wu-wien.ac.at:8000/xotcl-mailing-list/2992.html"...
Dear Prof. Neumann,
thank you very much for the detailed answer; your "patch" seems to solve the problem. For the time being, I will leave it as it is; if I encounter other unwanted side effects during testing I will have to delve deeper (which can be seen as a precondition to being able to answer your questions).
All the best, Michael
On Mon, Oct 12, 2015 at 5:10 PM, Michael Aram michael@aram.at wrote:
Dear XOTcl/NX/NSF community,
I am in the process of upgrading one of our OpenACS based systems to XOTcl 2 and stumbled over the following legacy code:
Class create Person -slots { foreach e {username first_names last_name email etcetera} { Attribute $e -default "" -proc assign {o var value} {$o changed_var $var $value} } }
Person ad_instproc -private changed_var {var value} {} { my instvar __changed_vars lappend __changed_vars $var my instvar $var set $var $value }
The intention of this not-so-pretty code mainly seems to be that the Person->save method called by code like the following can recognize which attributes have actually changed during the last request, and update the database accordingly...
Person john john last_name doe john save
For some reason, now that I have upgraded the system to XOTcl 2, this does not work anymore. The list __changed_vars is not updated (in the example above, it would not contain last_name; for debugging purposes, I have put a log statement into the "assign" proc, it seems that it does not get called.)
As the update process introduced many many other changes as well (compared to the old and adapted OpenACS we had there), including changes in xotcl-core, it could certainly be the case that this is simply a the side-effect of some other change / or messed-up merge. So, my question is, SHOULD this work anyway in the latest stable version of XOTcl 2, or did the interface change?
Thanks for your help, Michael :-)