Itcl - the [incr Tcl] extension

View Ticket
Login
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