View · Search · Index
No registered users in community xowiki
in last 10 minutes

Re: [Xotcl] Incorrect behavior?

From: Victor Mayevski <vitick_at_gmail.com>
Date: Wed, 29 Jun 2011 21:27:27 -0700

Thank you Gustaf for detailed explanation. My primary reason for using
attributes and such is to reduce verbosity in my code. I like clean,
short and simple code. With XOTcl/NX it is often a trade off between
flexibility/power and simplicity. So, I am trying to find that middle
ground. :) I will probably end up eventually rewriting my code to use
TCL variables, but it is good enough for now.

Thanks again,

Victor

On Wed, Jun 29, 2011 at 12:11 PM, Gustaf Neumann <neumann_at_wu.ac.at> wrote:
> Dear Victor,
>
> an attribute and an instance variable are two different things with
> potentially different life-times.
>
> - The attribute provides information about instance variables
>   and their properties (such as e.g. default values, which are
>   used when variables are to be created, or methods to access
>   the variable, etc.).
> - The instance variables keep the actual value, they can be
>  independently set and unset by standard Tcl commands.
>
> Therefore, changing the default value of an attribute does not change its
> actual value.
> The same holds for class-level attributes and object-level attributes.
>
> See e.g.
> ========================
> % Object create o {set :a 1}
> ::o
> %  o attribute {a oldvalue}
> ::o::a
> % o a
> 1
> ========================
>
> However, in some respects the object-level attributes are different from the
> class level attributes: In contrary to the class-level attributes, the
> object-level attributes check at definition time of the attribute, if an
> according instance variable exists. If not, it creates the instance variable
> with the default value. Probably therefore, you assumed, that the provided
> value is used to set always the instance variable (maybe influenced by Tcl's
> "variable" command).
>
> Since the attribute and the instance variable have different life-times,
> deleting the attribute does the fuzz with the the instance variable. Note
> that after deleting the attribute, the instance variable still exists (see
> last command below).
> ====================================
> % Object create o {:attribute {x 1}}
> ::o::per-object-slot::x init methodname=x
> ::o
> % o eval {set :x}
> 1
> % o x
> 1
> %  o delete attribute x
> % o x
> ::o: unable to dispatch method 'x'
>    while executing
> "o x"
> % o eval {set :x}
> 1
> ====================================
>
> Note, that the same holds as well for class-level attributes (changing
> default values, deleting attributes in class level attributes does not
> effect the variables in already created instances).
>
> One can certainly argue, that the behavior for object-level and class-level
> attributes does not have to be the same, and that e.g. the life-time of
> object-level attributes and instance variables should be stronger tied
> together (defining a object-level attribute should immediately
> create/overwrite instance variables, altering the default should change its
> value, deleting object-level attributes should remove the variables, etc.).
>
> One could define currently mixins that could achieve this strong binding.
> Note, that the other way round, if we hard-wire the strong binding, it is
> much more effort to get rid of this strong interaction. Note as well, that
> per-object attributes are a quite heavy-weight machinery for setting
> variables. I would certainly not recommend to use per-object attributes each
> time a variable has to be created, at least not in in performance critical
> or memory critical situations.
>
> I could see at least 3 scenarios for objects, that require sometimes
> instance attributes:
>
> a) lightweight: just use tcl-variables, no attributes
>
>      Object create o {
>         set :x 1
>         :public method foo {} {return ${:x}}
>       }
>
> b) middleweight: just tcl-variables + setters/checkers, no attributes
>
>      Object create o {
>         set :x 1
>         ::nsf::method::setter [self] x:integer
>         :public method foo {} {return ${:x}}
>       }
>       % o x
>        1
>        % o x a
>         expected integer but got "a" for parameter "x"
>
> c) heavyweight: use attributes
>
>      Object create o {
>         set :x 1
>         :attribute {x:integer,1..n 0} {set :incremental 1}
>         :public method foo {} {return ${:x}}
>       }
>
>       % o x
>       1
>       % o x add 10
>       10 1
>        % o x add 100
>        100 10 1
>        % o x
>        100 10 1
>        % o x {1 hello 2}
>        invalid value in "1 hello 2": expected integer but got "hello" for
> parameter "value"
>
> For (b) the middleweight version, we have currently no nice method-based
> interface.
> Just in the case of (c) with the incremental interface, slot objects are
> needed
> (as well in other cases, where some additional meta-data is needed, such as
> e.g. persistency data, etc.).
>
> We could do
>  (1) bind the life-time of per-object attributes to the life-time of
> instance variables
>  (2) create not always slots, when attribute is used, but only when needed.
>
> The case (2) could be tricky for "delete attribute", but at least, for often
> used per-object attributes this could be a win. What is your primary reason
> for using "attribute" instead of tcl vars? do you use the incremental
> setters?
>
>
> -gustaf neumann
>
>
> Am 29.06.11 19:52, schrieb Victor Mayevski:
>>
>> In my code I have objects that need some attributes only sometimes.
>> So, that was my attempt to reduce the code and not have to test for
>> the existence of that attribute but just re-create it. In this case, I
>> ended up just having that attribute permanently in all objects at all
>> times. It is not that I didn't have any other way of doing it, it is
>> just that I thought it would have been an elegant and short way of
>> doing it.
>>
>>
>> Here is another curious code that could be a bug, at least it doesn't
>> seem to behave as expected:
>>
>> % Object create o
>> ::o
>> % o attribute {a oldvalue}
>> ::o::a
>> % o a
>> oldvalue
>> % o delete attribute a
>> % o a
>> ::o: unable to dispatch method 'a'
>> % o attribute {a newvalue}
>> ::o::a
>> % o a
>> oldvalue
>>
>>
>>
>> Also, is it possible for "object delete attribute a" to not complain
>> if the attribute does not exist, may be via "-nocomplain" switch or
>> just by default?
>>
>> Thanks,
>>
>> Victor
>>
>>
>> On Wed, Jun 29, 2011 at 3:51 AM, Stefan Sobernig
>> <stefan.sobernig_at_wu.ac.at>  wrote:
>>>
>>> Victor,
>>>
>>>>> %Object create o
>>>>> ::o
>>>>> %o attribute {a oldvalue}
>>>>> ::o::a
>>>>> %o a
>>>>> oldvalue
>>>>> %o attribute {a newvalue}
>>>>> ::o::a
>>>>> %o a
>>>>> oldvalue
>>>
>>> Forgot to ask: Why do you take this path (changing the default of the
>>> attribute slot) in the first place? If you want "a" to have the value
>>> "newvalue" assigned, why don't you simply say:
>>>
>>> o a newvalue
>>>
>>> //s
>>>
>>>
>>>
>> _______________________________________________
>> Xotcl mailing list
>> Xotcl_at_alice.wu-wien.ac.at
>> http://alice.wu-wien.ac.at/mailman/listinfo/xotcl
>
>
> --
> Univ.Prof. Dr. Gustaf Neumann
> Institute of Information Systems and New Media
> WU Vienna
> Augasse 2-6, A-1090 Vienna, AUSTRIA
>
> _______________________________________________
> Xotcl mailing list
> Xotcl_at_alice.wu-wien.ac.at
> http://alice.wu-wien.ac.at/mailman/listinfo/xotcl
>