Jim Tcl: variables in namespace eval? sourcing non-regular files?

61 views
Skip to first unread message

Ivan Shmakov

unread,
Jun 9, 2022, 3:48:02 PMJun 9
to
I've recently stumbled on the different treatment of variables
in namespace eval body between Jim Tcl (as of 0.81 nb 1,
0.79 +dfsg0-2 and 0.77 +dfsg0-3 [1-3]) and Tcl 8.6.

[1] http://pkgsrc.se/lang/jimtcl
[2] http://packages.debian.org/bullseye/jimsh
[3] http://packages.debian.org/buster/jimsh

Namely, while namespace eval foo { set bar 42 } assigns to
the foo::bar variable in the latter, it appears like in Jim,
the same code rather modifies a variable local to the
namespace eval body itself; for instance, the following code
prints 42 in 8.6, but 1 in Jim:

namespace eval foo { } ; set foo::bar 1
namespace eval foo { set bar 42 }
puts [ set foo::bar ]

(It sure looks like that Jim likes its anonymous procedures
to a fault, or does it?)

Of course it's possible to namespace upvar in Jim (but not
in Tcl 8.6); and a workaround that appears to run the same
in either implementation is to introduce a separate "nset"
command:

proc nset { varn args } {
set p [ uplevel 1 { ::namespace current } ]
if { "::" ne $p } { append p :: }
## .
set ${p}$varn {*}$args
}

namespace eval foo { } ; set foo::bar 1
namespace eval foo { nset bar 42 } ; ## sets foo::bar in both Jim and 8.6
puts [ set foo::bar ] ; ## prints 42

Thoughts?

Another issue with Jim is that the 'source' command somehow
silently ignores non-regular files, such as pipes and character
specials. Same goes for such files passed as an argument to
the interpreter; for example:

bash$ jimsh <(printf %s\\n "puts 42")
bash$ tclsh8.6 <(printf %s\\n "puts 42")
42
bash$

Note that doing stat(2) on the /dev/fd/XX file (that is used
to implement Bash <() pipe) in the example above, identifies
the file as a pipe in Linux-based systems, but as a character
special in NetBSD (unless mount_fdesc(8) is in use, in which
case it is also identified as a pipe in this case.)

Is there any particular reason for such a behavior?

TIA.

--
FSF associate member #7257 http://am-1.org/~ivan/

Robert Heller

unread,
Jun 9, 2022, 5:17:47 PMJun 9
to
At Thu, 9 Jun 2022 19:47:49 +0000 Ivan Shmakov <iv...@siamics.netREMOVE.invalid> wrote:

>
> I've recently stumbled on the different treatment of variables
> in namespace eval body between Jim Tcl (as of 0.81 nb 1,
> 0.79 +dfsg0-2 and 0.77 +dfsg0-3 [1-3]) and Tcl 8.6.
>
> [1] http://pkgsrc.se/lang/jimtcl
> [2] http://packages.debian.org/bullseye/jimsh
> [3] http://packages.debian.org/buster/jimsh
>
> Namely, while namespace eval foo { set bar 42 } assigns to
> the foo::bar variable in the latter, it appears like in Jim,
> the same code rather modifies a variable local to the
> namespace eval body itself; for instance, the following code
> prints 42 in 8.6, but 1 in Jim:
>
> namespace eval foo { } ; set foo::bar 1
> namespace eval foo { set bar 42 }

Do you really mean:

namespace eval foo {
variable bar
set bar 42
}

???

Wondering if the bug is not what you think it is.

Maybe Tcl 8.6, when it see "set foo::bar ...", it automagically implies a
namespace eval foo {variable bar} and Jim does not. (Not sure if that is a
bug in Jim or Tcl 8.6.)
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
hel...@deepsoft.com -- Webhosting Services

Ivan Shmakov

unread,
Jun 9, 2022, 9:57:59 PMJun 9
to
>>>>> On 2022-06-09 16:17:37 -0500, Robert Heller wrote:
>>>>> At Thu, 9 Jun 2022 19:47:49 +0000 Ivan Shmakov wrote:

[...]

>> Namely, while namespace eval foo { set bar 42 } assigns to
>> the foo::bar variable in the latter, it appears like in Jim,
>> the same code rather modifies a variable local to the
>> namespace eval body itself; for instance, the following code
>> prints 42 in 8.6, but 1 in Jim:

>> namespace eval foo { } ; set foo::bar 1
>> namespace eval foo { set bar 42 }

> Do you really mean:

> namespace eval foo {
> variable bar
> set bar 42
> }

> ???

That's it; I've totally missed there needs to be a 'variable'
command! Somehow, it doesn't seem to be documented in Jim's
Tcl.html, which may be the reason why, to think of it.

Now I get the consistent behavior; thanks.

> Wondering if the bug is not what you think it is.

> Maybe Tcl 8.6, when it see "set foo::bar ...", it automagically
> implies a namespace eval foo {variable bar} and Jim does not.
> (Not sure if that is a bug in Jim or Tcl 8.6.)

No, the behavior of "set foo::bar ..." is entirely consistent
between Jim and 8.6: if the namespace variable named does not
exist, it's created. The only requirement is that the
namespace itself should exist; otherwise either the namespace
is silently created (Jim), or the command fails (Tcl 8.6.)

Steve Bennett

unread,
Jun 14, 2022, 5:41:00 AMJun 14
to
On Friday, June 10, 2022 at 5:48:02 AM UTC+10, Ivan Shmakov wrote:

>
> Another issue with Jim is that the 'source' command somehow
> silently ignores non-regular files, such as pipes and character
> specials. Same goes for such files passed as an argument to
> the interpreter; for example:
>
> bash$ jimsh <(printf %s\\n "puts 42")
> bash$ tclsh8.6 <(printf %s\\n "puts 42")
> 42
> bash$
>
> Note that doing stat(2) on the /dev/fd/XX file (that is used
> to implement Bash <() pipe) in the example above, identifies
> the file as a pipe in Linux-based systems, but as a character
> special in NetBSD (unless mount_fdesc(8) is in use, in which
> case it is also identified as a pipe in this case.)
>
> Is there any particular reason for such a behavior?

Jim stats the file, sees a size of zero and does nothing.
It would be possible to change that but it seems low value.
Perhaps send a patch to jimtcl on GitHub if you think is worth changing.

Cheers,
Steve
Reply all
Reply to author
Forward
0 new messages