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

Re: [Xotcl] Attributes bug?

From: Gustaf Neumann <neumann_at_wu.ac.at>
Date: Mon, 25 Jun 2012 11:52:41 +0200

Dear all,

the same problem as reported by Kurt Stoll exists as well in
nx/xotcl2.
Since the new implementation has already an elaborated resolver
infrastructure, and since it already flags slot container
objects as such,
i have added a specialized resolver for handling this
unwanted interaction.

The test case below works now correctly.

-gustaf neumann

nx::Test case slot-container-name-interaction {

   nx::Class create Test2 {
     :property list {
       :public method assign { obj var val } {
        nsf::var::set $obj $var [list $obj $var $val]
       }
       :method unknown { val obj var args } {
        return unknown
       }
     }
   }

   ? {Test2 create t2} ::t2
   ? {t2 list 3} {::t2 list 3}
   ? {t2 list} {::t2 list 3}
   ? {t2 list this should call unknown} "unknown"
}


On 25.06.12 09:30, Gustaf Neumann wrote:
> Dear Kurt,
>
> Replace in the assign method
> $obj set $var [list $obj $var $val]
>
> by
> $obj set $var [::list $obj $var $val]
>
> Background: the created slot object2 ("alist" and "list")
> are fully named
>
> ::Test1::slot::alist
> ::Test1::slot::list
>
> In order to create these conveniantely (i.e. without
> requiring the user to write the namespaces explicitly),
> the method "slots" changes the current namespace to
> "::Test1::slot". The method "assign" is executed
> in this namespace (::Test1::slot), and picks up the
> "::Test1::slot::list" instead of the desired "::list".
> Therefore, using the explicit namespace path for "::list"
> helps.
>
> The only way to get rid of this unexpected behavior is to
> introduce a namespace resolver for the
> slot object container, that overrides the Tcl behavior.
>
> -gustaf neumann
>
> On 25.06.12 00:54, Kurt Stoll wrote:
>> This looks wrong to me, but I could be wrong - maybe
>> there are prohibitions somewhere that would tell me not
>> to do this.
>>
>> If I define an Attribute "list", and then use the Tcl
>> list command within the assign (and, presumably, other
>> procs of the attribute as well), the attribute's unknown
>> handler is called reflecting an odd invocation. I would
>> suspect that other "overloading" (this is not really
>> overloading, but looks similar so I have used that term;
>> I apologize it that confuses you) of Tcl commands as
>> Attributes would result in similar problems.
>>
>> First, here is a simple Test class without overloading
>> the list command to demonstrate the expected behavior.
>> Note that I redefine unknown so that I can verify the
>> order of the invocation:
>>
>> (Warning - I submitted a question with embedded test code
>> some years ago and this caused problems for people when
>> they attempted to copy-and-paste the code. I don't
>> recall exactly what caused the issue, but I am still
>> using the same email client, so this may have similar
>> issues.)
>>
>> Class create Test1 -slots {
>> Attribute create alist -proc assign { obj var val } {
>> puts "list<$obj> <$var> <$val>"
>> $obj set $var [list $obj $var $val]
>> } -proc unknown { val obj var args } {
>> puts "unknown: $obj $var $val $args"
>> }
>> }
>>
>>> ## Create a test object t1
>>> Test1 create t1
>> ::t1
>>> ## Call alist setter
>>> t1 alist 3
>> list<::t1> <alist> <3>
>> ::t1 alist 3
>>> ## Check to see that alist variable set properly
>>> t1 set alist
>> ::t1 alist 3
>>> ## Force a call to unknown; note that the printed output
>>> matches the invocation order
>>> t1 alist this should call unknown
>> unknown: ::t1 alist this should call unknown
>>
>> Now, I create a simple variant. All I have changed is
>> the name of the Attribute from "alist" to "list". But,
>> in this case, when attempting to call the setter, unknown
>> is called (I have done other experiments that showed that
>> it is called when "list $obj $var $val" is called).
>> Also, note that the invocation of unknown is a bit
>> strange; it appears that unknown is directly invoked on
>> the original call (in this case, "t2 list 3"), instead of
>> having the arguments swapped as demonstrated above:
>>
>> Class create Test2 -slots {
>> Attribute create list -proc assign { obj var val } {
>> puts "list<$obj> <$var> <$val>"
>> $obj set $var [list $obj $var $val]
>> } -proc unknown { val obj var args } {
>> puts "unknown: $obj $var $val $args"
>> }
>> }
>>
>>> ## Create a test object t2
>>> Test2 create t2
>> ::t2
>>> ## Call list setter. Unknown handler is called.
>>> t2 list 3
>> list<::t2> <list> <3>
>> unknown: list 3 ::t2
>>> ## See what ended up in the list variable.
>>> t2 set list
>>> ## Blank above
>> Am I wrong to expect Test2 (and t2) to behave just as
>> Test1 / t1 behaved? It's not a serious issue for me;
>> I'll just avoid overloading Tcl commands in this
>> context. But, it was unexpected enough for me that I
>> thought it was warranted for me to ask the experts.
>>
>> -Kurt Stoll
>>
>> _______________________________________________
>> Xotcl mailing list
>> Xotcl_at_alice.wu-wien.ac.at
>> http://alice.wu-wien.ac.at/mailman/listinfo/xotcl
>
> _______________________________________________
> Xotcl mailing list
> Xotcl_at_alice.wu-wien.ac.at
> http://alice.wu-wien.ac.at/mailman/listinfo/xotcl