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

    From Ivan Shmakov@21:1/5 to All on Thu Jun 9 19:47:49 2022
    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/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Heller@21:1/5 to [email protected] on Thu Jun 9 16:17:37 2022
    At Thu, 9 Jun 2022 19:47:49 +0000 Ivan Shmakov <[email protected]d> 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.)

    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.


    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    [email protected] -- Webhosting Services

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ivan Shmakov@21:1/5 to All on Fri Jun 10 01:57:47 2022
    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.)

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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Bennett@21:1/5 to Ivan Shmakov on Tue Jun 14 02:40:58 2022
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)