Hi, if I import all the class commands from a namespace this causes an error
claiming that all the class commands already exists. Consider the script:
package require itcl
package require itk
namespace import itk::*
itcl::class Test {
inherit itk::Toplevel
constructor {args} {
puts "Construction: $this -> $args"
eval itk_initialize $args
}
destructor {
puts "Destruction: $this"
}
}
Test .t -title "New window"
When I run this against itcl-ng (with tcl8.6) I get the error:
Error in startup script: cannot inherit from "itk::Toplevel" (can't create object "itk::Toplevel": command already exists with that nameITCL: cannot create Tcl_NewObjectInstance for class "::itk::Toplevel")
while executing
"inherit itk::Toplevel"
(class "Test" body line 3)
invoked from within
"itcl::class Test {
inherit itk::Toplevel
constructor {args} {
puts "Construction: $this -> $args"
eval itk_initialize $args
}
..."
(file "itest.tcl" line 6)
Removing the "namespace import" line fixes the problem or moving
back to itcl 3.4.
test script
I have tracked down the problem. When calling namespace import command, Itcl is doing a call to auto_index_load, which in turn creates Itcl stubs commands for the imported commands. The proc command of the created command is set to an Itcl command, which in turn does an autoload when the command is called. So after import ::itk::* there exists an Itcl stubs command ::itk::Toplevel, which is not a class and which would be changed into a class when either there is a call to
1) create a class object i.e. ::itk::Toplevel xx
2) a class contains a inherit ::itk::Toplevel
case 1) would call the Itcl stubs command and create the class using auto_load
case 2) forces the auto_load when looking for the class
both cases calla create calls which in turn uses TclOO's class creation mechanism, which is the base for itcl-ng. In TclOO there is a call to Tcl_NewObjectInstance, which does not allow that a command with the same name already exists. Therfore I hve no way to force the creation of the command nevertheless, which is what itcl 3.4 does. DKF has to decide, if there is a possibility to change that behaviour evtl. using a special flag or something else. There is no solution for the problem in itcl-ng.
Refusing to magically delete an old command by accident is a designed-in feature (accidentally deleting a class that's high up the class hierarchy would be rather destructive!) A workaround would be to delete the stub command immediately before calling Tcl_NewObjectInstance (or it's script-level analogs, the construction methods 'create' and 'new').
Donal, I agree fully with your argumentation. Problem with deleting the stubs command before calling Tcl_NewObjectInstance is, that the imported command(s) are no longer valid afterwards. Tcl_CreateObjCommand command just removes the old command and reuses the Command structure, when creating the new one and reuses the references for the imported commands and "repairs" them afterwards. If you have a solution for that problem too, please let me know.
This Tracker item was closed automatically by the system. It was
previously set to a Pending status, and the original submitter
did not respond within 14 days (the time period specified by
the administrator of this Tracker).
reopened as no final solution yet.