Discussion:
Differing namespace behavior in Tcl 9.0b2
(too old to reply)
Andrew Mangogna
2024-07-16 21:52:17 UTC
Permalink
I have been out of the Tcl loop for a while, but have been porting an old
"C" based extension of mine to Tcl 9.0b2. The port went well, required
very few changes, but I have some differing behavior that I'm trying to
track down. The package consists of an ensemble command, "ral" which
has three subcommands implemented in the "::ral" namespace. Each of
the subcommands is also exported from the namespace. The following shows
the problems:

For Tcl 8.6:

% info patchlevel
8.6.11
% package require ral
0.12.2
% info commands ral
ral
% namespace export
% ral relvar names
% relvar names
invalid command name "relvar" <- expected
% namespace import ::ral::*
% relvar names
% namespace export
%

For Tcl 9.0b2:

% info patchlevel
9.0b2
% package require ral
0.13.0 <- new port to Tcl 9
% info commands ral
ral
% namespace export
tuple relation relvar <- unexpected -- ral exports these commands
<- but they shouldn't appear in the global
<- namespace
% ral relvar names
% relvar names
invalid command name "relvar" <- expected, just as Tcl 8.6
% namespace import ::ral::*
% relvar names
invalid command name "relvar" <- unexpected
% namespace export
tuple relation relvar <- again, not sure why these appear

So my question is, "Is there some namespace / ensemble changes that I've
not been able to track down?" It appears that the ensemble works
correctly, but that the exported commands are no longer exported or
available.

Thanks,

Andrew Mangogna
et99
2024-07-17 03:17:38 UTC
Permalink
Post by Andrew Mangogna
I have been out of the Tcl loop for a while, but have been porting an old
"C" based extension of mine to Tcl 9.0b2. The port went well, required
very few changes, but I have some differing behavior that I'm trying to
track down. The package consists of an ensemble command, "ral" which
has three subcommands implemented in the "::ral" namespace. Each of
the subcommands is also exported from the namespace. The following shows
% info patchlevel
8.6.11
% package require ral
0.12.2
% info commands ral
ral
% namespace export
% ral relvar names
% relvar names
invalid command name "relvar" <- expected
% namespace import ::ral::*
% relvar names
% namespace export
%
% info patchlevel
9.0b2
% package require ral
0.13.0 <- new port to Tcl 9
% info commands ral
ral
% namespace export
tuple relation relvar <- unexpected -- ral exports these commands
<- but they shouldn't appear in the global
<- namespace
% ral relvar names
% relvar names
invalid command name "relvar" <- expected, just as Tcl 8.6
% namespace import ::ral::*
% relvar names
invalid command name "relvar" <- unexpected
% namespace export
tuple relation relvar <- again, not sure why these appear
So my question is, "Is there some namespace / ensemble changes that I've
not been able to track down?" It appears that the ensemble works
correctly, but that the exported commands are no longer exported or
available.
Thanks,
Andrew Mangogna
I Don't know if this is your issue, but there is one incompatibility I know of in 9.0 from the release notes:


important Incompatibilities in Tcl 9.0

Namespace varname resolution: Current namespace, not global.


As far as I can tell, by looking up the manual for 9.0 from an internet search and finding

https://www.tcl-lang.com/man/tcl9.0/TclCmd/namespace.html

the manual entry on name resolution is not changed there from 8.6. However, I do know that some code I've used under 9.0 had to be changed when it assumed the old way. In particular some of the tcl_* globals needed to add :: in front of the variable names since it would no longer find them in the global namespace when used inside of a namespace without the ::tcl_*.
Ashok
2024-07-17 06:04:30 UTC
Permalink
See the "Change in variable name resolution" section in
https://core.tcl-lang.org/tcl/wiki?name=Migrating+scripts+to+Tcl+9&p
Post by Andrew Mangogna
So my question is, "Is there some namespace / ensemble changes that I've
not been able to track down?" It appears that the ensemble works
correctly, but that the exported commands are no longer exported or
available.
Thanks,
Andrew Mangogna
Ashok
2024-07-17 06:07:47 UTC
Permalink
Sorry, my previous post might be irrelevant. I thought your issue was
related to variable name resolution, not command ensembles.
Post by Andrew Mangogna
So my question is, "Is there some namespace / ensemble changes that I've
not been able to track down?" It appears that the ensemble works
correctly, but that the exported commands are no longer exported or
available.
Thanks,
Andrew Mangogna
Andreas Leitgeb
2024-07-17 08:04:13 UTC
Permalink
Post by Andrew Mangogna
I have been out of the Tcl loop for a while, but have been porting an old
"C" based extension of mine to Tcl 9.0b2. The port went well, required
very few changes, but I have some differing behavior that I'm trying to
track down. The package consists of an ensemble command, "ral" which
has three subcommands implemented in the "::ral" namespace. Each of
the subcommands is also exported from the namespace. The following shows
The behaviour looks buggy to me, but without knowing what
your package ral really does, it's hard to judge.

The only commonly known change w.r.t. namespaces in Tcl9 is
that change about variable lookup (already mentioned in other
replies).

Could you try to reproduce it with a simple package, that
exhibits the same difference 8.6 vs 9.0 ?
Post by Andrew Mangogna
% namespace export
tuple relation relvar <- unexpected -- ral exports these commands
<- but they shouldn't appear in the global
<- namespace
Maybe your code does an export on these commands, but only in Tcl9 it
effectively does the "export" from global namespace...

That *might* be a Tcl9 bug, but it would be very interesting how
that is triggered.

Btw., a command does not need to exist in a particular namespace to
be "export"-able from there.
Andrew Mangogna
2024-07-17 18:09:01 UTC
Permalink
Post by Andreas Leitgeb
Post by Andrew Mangogna
I have been out of the Tcl loop for a while, but have been porting an old
"C" based extension of mine to Tcl 9.0b2. The port went well, required
very few changes, but I have some differing behavior that I'm trying to
track down. The package consists of an ensemble command, "ral" which
has three subcommands implemented in the "::ral" namespace. Each of
the subcommands is also exported from the namespace. The following shows
The behaviour looks buggy to me, but without knowing what
your package ral really does, it's hard to judge.
The only commonly known change w.r.t. namespaces in Tcl9 is
that change about variable lookup (already mentioned in other
replies).
Could you try to reproduce it with a simple package, that
exhibits the same difference 8.6 vs 9.0 ?
Post by Andrew Mangogna
% namespace export
tuple relation relvar <- unexpected -- ral exports these commands
<- but they shouldn't appear in the global
<- namespace
Maybe your code does an export on these commands, but only in Tcl9 it
effectively does the "export" from global namespace...
That *might* be a Tcl9 bug, but it would be very interesting how
that is triggered.
Btw., a command does not need to exist in a particular namespace to
be "export"-able from there.
I didn't want to drop a big pile of code, but here is the package init
function where the commands and ensemble are created. This is old code,
most of it dating from 2014.

-----------
DLLEXPORT
int
ral_Init(
Tcl_Interp *interp)
{
static char const tupleCmdName[] = "::ral::tuple" ;
static char const tupleStr[] = "tuple" ;
static char const relationCmdName[] = "::ral::relation" ;
static char const relationStr[] = "relation" ;
static char const relvarCmdName[] = "::ral::relvar" ;
static char const relvarStr[] = "relvar" ;
static char const pkgNamespace[] = "::ral" ;

Ral_RelvarInfo rInfo ;
Tcl_Obj *mapObj ;
Tcl_Command ensembleCmdToken ;
Tcl_Namespace *ralNs ;

if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
return TCL_ERROR ;
}
if (Tcl_TomMath_InitStubs(interp, TCL_VERSION) == NULL) {
return TCL_ERROR ;
}
/*
* Create the namespace in which the package command reside.
*/
ralNs = Tcl_CreateNamespace(interp, pkgNamespace, NULL, NULL) ;
/*
* Create the package commands.
* First the "tuple" command.
*/
mapObj = Tcl_NewDictObj() ;
Tcl_CreateObjCommand(interp, tupleCmdName, tupleCmd, NULL, NULL) ;
if (Tcl_Export(interp, ralNs, tupleStr, 0) != TCL_OK) {
goto errorout ;
}
if (Tcl_DictObjPut(interp, mapObj,
Tcl_NewStringObj(tupleStr, -1),
Tcl_NewStringObj(tupleCmdName, -1)) != TCL_OK) {
goto errorout ;
}
/*
* Next the "relation" command.
*/
Tcl_CreateObjCommand(interp, relationCmdName, relationCmd, NULL,
NULL) ;
if (Tcl_Export(interp, ralNs, relationStr, 0) != TCL_OK) {
goto errorout ;
}
if (Tcl_DictObjPut(interp, mapObj,
Tcl_NewStringObj(relationStr, -1),
Tcl_NewStringObj(relationCmdName, -1)) != TCL_OK) {
goto errorout ;
}
/*
* Finally, the "relvar" command.
*/
rInfo = Ral_RelvarNewInfo(ral_pkgname, interp) ;
Tcl_CreateObjCommand(interp, relvarCmdName, relvarCmd, rInfo, NULL) ;
if (Tcl_Export(interp, ralNs, relvarStr, 0) != TCL_OK) {
goto errorout ;
}
if (Tcl_DictObjPut(interp, mapObj,
Tcl_NewStringObj(relvarStr, -1),
Tcl_NewStringObj(relvarCmdName, -1)) != TCL_OK) {
}
/*
* Create an ensemble command on the namespace.
*/
ensembleCmdToken = Tcl_CreateEnsemble(interp, "::ral", ralNs, 0) ;
/*
* Following the pattern in Tcl sources, we set the mapping dictionary
* of the ensemble. This will allow the ensemble to be extended
* at the script level.
*/
if (Tcl_SetEnsembleMappingDict(interp, ensembleCmdToken, mapObj) !=
TCL_OK) {
goto errorout ;
}
/*
* Support for package configuration.
*/
Tcl_RegisterConfig(interp, ral_pkgname, ral_config, "iso8859-1") ;

Tcl_PkgProvide(interp, ral_pkgname, ral_version) ;

return TCL_OK ;

errorout:
Tcl_DecrRefCount(mapObj) ;
return TCL_ERROR ;
}
-----------

Andrew Mangogna

Loading...