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

Re: [Xotcl] Incorrect behavior?

From: Gustaf Neumann <neumann_at_wu.ac.at>
Date: Wed, 29 Jun 2011 21:11:39 +0200

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