Ticket Hash: | a956a5d397c82977e05ab92e6cc9bb3081e9af24 | |||
Title: | info heritage returns class list based on where method is defined as opposed to object class | |||
Status: | Closed | Type: | Code_Defect | |
Severity: | Important | Priority: | Immediate | |
Subsystem: | Resolution: | Fixed | ||
Last Modified: | 2015-01-21 13:48:45 | |||
Version Found In: | Itcl 4.0.2+Tcl 8.6.3 | |||
User Comments: | ||||
apnadkarni added on 2014-12-08 12:07:44:
Example: package require Itcl itcl::class B { public method hierarchy {} { return [$this info heritage] } } itcl::class C { inherit B public method hierarchy {} { return [$this info heritage] } } itcl::class D { inherit B } Then, (tcl) 49 % C #auto c0 (tcl) 51 % c0 hierarchy ::C ::B (tcl) 52 % D #auto d0 (tcl) 53 % d0 hierarchy ::B I would expect [d0 hierarchy] to return ::D ::B since the object class is D. I believe (based on communication with the author of the package where I ran into this bug), this is an incompatibility wrt Itcl 3.x as he uses that version and does not see this problem. apnadkarni added on 2014-12-08 12:23:39: The same issue also holds for the [info inherit]. package require Itcl itcl::class B { public method hierarchy {} { return [$this info heritage] } public method inherited {} { return [$this info inherit] } } itcl::class C { inherit B public method hierarchy {} { return [$this info heritage] } public method inherited {} { return [$this info inherit] } } itcl::class D { inherit B } (tcl) 49 % C #auto c0 (tcl) 50 % D #auto d0 (tcl) 51 % c0 inherited ::B (tcl) 52 % d0 inherited However, if we call the info method from the global scope directly , it works correctly. (tcl) 53 % d0 info heritage ::D ::B (tcl) 54 % c0 info heritage ::C ::B (tcl) 55 % d0 info inherit ::B (tcl) 56 % c0 info inherit ::B /Ashok dgp added on 2015-01-02 22:51:37: confirmed I also see this difference between Itcl 3 and Itcl 4. dgp added on 2015-01-05 20:24:28: The trouble here is in the machinery used to invoke d0 info heritage The d0 object doesn't in fact have an info method. Instead a handler in the unknown method is used, essentially this: method unknown args {uplevel 1 ::itcl::builtin::objectunknown d0 $args} Ok, so the next mystery is why that d0 argument isn't getting used to get the right answer. dgp added on 2015-01-05 21:05:13: No that doesn't seem to be right. dgp added on 2015-01-05 21:19:23: Sorry, I give up. Need a dual expert in both TclOO and Itcl to make any progress on this. I'm neither. dgp added on 2015-01-05 21:25:53: There's a routine Itcl_BiInfoHeritageCmd() within itclInfo.c where the functioning apparently takes place. From the comments, it seems that the result is dependent on the current namespace of the interp when that routine is called. That namespace needs to be and Itcl class namespace to avoid an error, and it needs to be the right Itcl class namespace to get proper functioning. Somehow, whatever path that is actually followed (which I cannot untangle) doesn't set the right current namespace to get the right answer. No idea if that much info in the hands of someone who knows something makes it easy to fix or not. dgp added on 2015-01-15 17:59:15: In Itcl 3 there are a pair of routines Itcl_PushContext() and Itcl_PopContext() that are called going in and coming out of a method body invocation, and they have the effect of chaning the current namespace appropriately so that the [$obj info] subcommands see the context they need to produce correct results. In Itcl 4, those routines no longer exist. If they did, it seems possible that calls to them might be added to ItclCheckCallMethod() and ItclAfterCallMethod() to get the same sort of context switch at the right point (following the pattern of Itcl_PushStack and Itcl_PopStack). Anyone reading this who knows the history of the purging of Itcl_(Push|Pop)Context might be able to point the way to a proper fix here. dgp added on 2015-01-16 15:26:44: See branch bug-a956a5d397 for work in progress. dgp added on 2015-01-20 20:35:17: More progress on the branch. dgp added on 2015-01-21 13:48:45: Fix committed to trunk and to 4.0.3 release branch |