• variable ../.. global

    From Roderick@hruodr@gmail.com to comp.lang.tcl on Sun Feb 22 22:57:48 2026
    From Newsgroup: comp.lang.tcl


    The man page of variable is in some things not very explicit.
    I have some questions.

    Question 1:

    What is the difference between:

    namespace eval foo {variable bar 12345}

    and

    namespace eval foo {set bar 12345}

    Do not create both namespace variable?

    Is "variable" about allocating space for the variable if there is
    no value in the declaration?


    Question 2:

    I read "If the variable command is executed inside a Tcl procedure,
    it creates local variables linked to the corresponding namespace
    variables"

    Does it also create the namespace variable? Or I need also to
    execute it outside the procedure?


    Question 3

    I want to source a script, perhaps inside a name space, perhaps not,
    and I want instead of global, variables only visible in the name space.

    Is the solution to change "global var" with "namespace var"?

    Thanks for any hint!

    Rod.
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Rich@rich@example.invalid to comp.lang.tcl on Sun Feb 22 23:25:22 2026
    From Newsgroup: comp.lang.tcl

    Roderick <hruodr@gmail.com> wrote:

    The man page of variable is in some things not very explicit.
    I have some questions.

    Question 1:

    What is the difference between:

    namespace eval foo {variable bar 12345}

    and

    namespace eval foo {set bar 12345}

    When executed like that, both create the variable ::foo::bar

    Is "variable" about allocating space for the variable if there is
    no value in the declaration?

    It is about linking proc variables to namespace variables. It can also
    be used outside a proc within a namespace, but then it is not so
    different from 'set', One difference is 'variable bar' makes the
    variable exist, but leaves it undefined (no value).

    Question 2:

    I read "If the variable command is executed inside a Tcl procedure,
    it creates local variables linked to the corresponding namespace
    variables"

    Does it also create the namespace variable? Or I need also to
    execute it outside the procedure?

    The docs answer that question for you. Note last sentence in the quote
    below from the namespace manpage.:

    You can access a namespace variable from a procedure in the same
    namespace by using the variable command. Much like the global
    command, this creates a local link to the namespace variable. If
    necessary, it also creates the variable in the current namespace and
    initializes it.

    Question 3

    I want to source a script, perhaps inside a name space, perhaps not,
    and I want instead of global, variables only visible in the name space.

    Is the solution to change "global var" with "namespace var"?

    "namespaced variables" are effectively "global like" within the
    namespace itself (they exist outside of proc's, just like globals exist outsite of proc's). So changing "global var" to "variable var" would
    link each of those to a namespaced variable instead of a global.

    Whether it works for a given bit of code will depend upon what the rest
    of that code attempts to do when accessing the variable. If it
    accesses globals as "set ::gvar 2" or "set ::gvar" then just changing
    "global" to "variable" won't help, because the code forces those
    variables to be in the global namespace by the explit paths.

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Roderick@hruodr@gmail.com to comp.lang.tcl on Mon Feb 23 00:09:33 2026
    From Newsgroup: comp.lang.tcl


    Thanks a lot, Rich!

    On Sun, 22 Feb 2026, Rich wrote:

    The docs answer that question for you. Note last sentence in the quote
    below from the namespace manpage.:

    You can access a namespace variable from a procedure in the same
    namespace by using the variable command. Much like the global
    command, this creates a local link to the namespace variable. If
    necessary, it also creates the variable in the current namespace and
    initializes it.

    Very interesting!

    Also the two sentences that follow:

    "Note that the global command only creates links to variables in
    the global namespace. It is not necessary to use a variable command
    if you always refer to the namespace variable using an appropriate
    qualified name."

    I suppose the phrase "links to variables in the global namespace"
    in the first sentence means "links to variables relative to
    the global namespace".

    If I have a variable v in the namespace name, then

    "global ::name::v" and "variable v" inside a procedure in
    "namespace eval name" will do the same.

    It seems the command "variable" is necessary because "global" is
    unable to deal with paths relative to the namespace.

    Am I wrong?

    Rod.
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Rich@rich@example.invalid to comp.lang.tcl on Mon Feb 23 03:32:46 2026
    From Newsgroup: comp.lang.tcl

    Roderick <hruodr@gmail.com> wrote:

    Thanks a lot, Rich!

    On Sun, 22 Feb 2026, Rich wrote:

    The docs answer that question for you. Note last sentence in the quote
    below from the namespace manpage.:

    You can access a namespace variable from a procedure in the same
    namespace by using the variable command. Much like the global
    command, this creates a local link to the namespace variable. If
    necessary, it also creates the variable in the current namespace and
    initializes it.

    Very interesting!

    Also the two sentences that follow:

    "Note that the global command only creates links to variables in
    the global namespace. It is not necessary to use a variable command
    if you always refer to the namespace variable using an appropriate
    qualified name."

    I suppose the phrase "links to variables in the global namespace"
    in the first sentence means "links to variables relative to
    the global namespace".

    Well, given that the "global namespace" (::) is also the root for all
    the other namespaces, yes.

    If I have a variable v in the namespace name, then

    "global ::name::v" and "variable v" inside a procedure in
    "namespace eval name" will do the same.

    The point of "global" is to make a "local proc variable" link to a global
    of the same name. ::name::v is not a "local proc variable". Trying to
    do that won't make the link.

    You do realize you can test some of these ideas out yourself to see
    what happens, right:

    $ rlwrap tclsh
    % info globals
    tcl_rcFileName tcl_version argv0 argv tcl_interactive auto_path
    auto_index env tcl_pkgPath tcl_patchLevel argc tcl_library tcl_platform
    % namespace eval ::newnamespace { namespace current }
    ::newnamespace
    % proc ::newnamespace::abc {} { global ::abc:pdq ; set pdq 1 }
    % ::newnamespace::abc
    1
    % namespace children ::
    ::zlib ::oo ::newnamespace ::tcl
    % info globals
    tcl_rcFileName tcl_version argv0 argv tcl_interactive auto_path
    auto_index env tcl_pkgPath tcl_patchLevel argc tcl_library tcl_platform
    %

    "global ::abc::pdq" did not create a new namespace, nor did it actually
    set a global variable.

    It seems the command "variable" is necessary because "global" is
    unable to deal with paths relative to the namespace.

    'variable' is necessary because the semantics of 'global', which were
    set years before Tcl grew namespaces, is incompatible with linking to namespace variables from inside procs. "global" is defined as always
    linking to the global namespace.

    Variable is "similar to 'global', but works within a namespace".

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Schelte@nospam@wanadoo.nl to comp.lang.tcl on Mon Feb 23 09:51:54 2026
    From Newsgroup: comp.lang.tcl

    On 22/02/2026 23:57, Roderick wrote:
    What is the difference between:

    namespace eval foo {variable bar 12345}

    and

    namespace eval foo {set bar 12345}

    Do not create both namespace variable?

    On Tcl 8 it depends. If there is already a global variable "bar", your
    second command will change the value of the global variable, rather than create a namespace variable:

    % set bar 42
    42
    % namespace eval foo {set bar 12345}
    12345
    % set bar
    12345
    % info exists ::foo::bar
    0

    See tip #278: https://core.tcl-lang.org/tips/doc/trunk/tip/278.md


    Schelte.

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Roderick@hruodr@gmail.com to comp.lang.tcl on Mon Feb 23 09:08:43 2026
    From Newsgroup: comp.lang.tcl


    On Mon, 23 Feb 2026, Rich wrote:

    If I have a variable v in the namespace name, then

    "global ::name::v" and "variable v" inside a procedure in
    "namespace eval name" will do the same.

    The point of "global" is to make a "local proc variable" link to a global
    of the same name. ::name::v is not a "local proc variable". Trying to
    do that won't make the link.

    I meant this:

    % namespace eval nn {proc pp {} {global ::nn::v; set v 1}}
    % nn::pp
    1
    % set nn::v
    1

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Roderick@hruodr@gmail.com to comp.lang.tcl on Mon Feb 23 09:14:00 2026
    From Newsgroup: comp.lang.tcl


    Terrible, that looks like a bug.

    On Mon, 23 Feb 2026, Schelte wrote:

    On 22/02/2026 23:57, Roderick wrote:
    What is the difference between:

    namespace eval foo {variable bar 12345}

    and

    namespace eval foo {set bar 12345}

    Do not create both namespace variable?

    On Tcl 8 it depends. If there is already a global variable "bar", your second
    command will change the value of the global variable, rather than create a namespace variable:

    % set bar 42
    42
    % namespace eval foo {set bar 12345}
    12345
    % set bar
    12345
    % info exists ::foo::bar
    0

    See tip #278: https://core.tcl-lang.org/tips/doc/trunk/tip/278.md


    Schelte.


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Rich@rich@example.invalid to comp.lang.tcl on Mon Feb 23 19:41:02 2026
    From Newsgroup: comp.lang.tcl

    Roderick <hruodr@gmail.com> wrote:

    On Mon, 23 Feb 2026, Rich wrote:

    If I have a variable v in the namespace name, then

    "global ::name::v" and "variable v" inside a procedure in
    "namespace eval name" will do the same.

    The point of "global" is to make a "local proc variable" link to a global
    of the same name. ::name::v is not a "local proc variable". Trying to
    do that won't make the link.

    I meant this:

    % namespace eval nn {proc pp {} {global ::nn::v; set v 1}}
    % nn::pp
    1
    % set nn::v
    1

    Interesting, so within the same namespace, applying global to a fully qualified variable name looks to do the same thing as 'variable'.

    But, it does not work for namespaces that do not yet exist:

    $ rlwrap tclsh
    % namespace eval nn {proc pp {} {global ::nn::v; set v 1}}
    % set nn::v
    can't read "nn::v": no such variable
    % nn::pp
    1
    % set nn::v
    1

    Continue with a test of a non-existant namespace:

    % namespace eval nn2 {proc pp2 {} {global ::nn3::v; set v 1}}
    % set nn3::v
    can't read "nn3::v": no such variable
    % nn2::pp2
    can't access "::nn3::v": parent namespace doesn't exist
    %

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Roderick@hruodr@gmail.com to comp.lang.tcl on Wed Feb 25 07:10:40 2026
    From Newsgroup: comp.lang.tcl


    On Mon, 23 Feb 2026, Rich wrote:

    Continue with a test of a non-existant namespace:

    % namespace eval nn2 {proc pp2 {} {global ::nn3::v; set v 1}}
    % set nn3::v
    can't read "nn3::v": no such variable
    % nn2::pp2
    can't access "::nn3::v": parent namespace doesn't exist


    # tclsh
    % global ::nn3::v
    % % set ::nn3::v 1
    invalid command name "%"
    % variable ::nn3::v
    can't define "::nn3::v": parent namespace doesn't exis

    I think, that is a difference between global and variable.
    The last do allocate memory, the first only signalizes that
    a local var in procedure is bound to other var that perhaps
    does not exist yet.


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Rich@rich@example.invalid to comp.lang.tcl on Wed Feb 25 16:07:18 2026
    From Newsgroup: comp.lang.tcl

    Roderick <hruodr@gmail.com> wrote:

    On Mon, 23 Feb 2026, Rich wrote:

    Continue with a test of a non-existant namespace:

    % namespace eval nn2 {proc pp2 {} {global ::nn3::v; set v 1}}
    % set nn3::v
    can't read "nn3::v": no such variable
    % nn2::pp2
    can't access "::nn3::v": parent namespace doesn't exist


    # tclsh
    % global ::nn3::v
    % % set ::nn3::v 1
    invalid command name "%"
    % variable ::nn3::v
    can't define "::nn3::v": parent namespace doesn't exis

    I think, that is a difference between global and variable.
    The last do allocate memory, the first only signalizes that
    a local var in procedure is bound to other var that perhaps
    does not exist yet.

    Small syntax error on line 3:

    $ rlwrap tclsh
    % global ::nn3::v
    % set ::nn3::v 1
    can't set "::nn3::v": parent namespace doesn't exist
    % variable ::nn3::v
    can't define "::nn3::v": parent namespace doesn't exist
    %

    --- Synchronet 3.21b-Linux NewsLink 1.2