• Re: How to read a namespace variable when using variable name in namesp

    From Harald Oehlmann@21:1/5 to All on Mon Aug 25 21:33:51 2025
    Am 25.08.2025 um 20:56 schrieb [email protected]:
    Hi,

    In the example code below, I try to access a proc and a variable in a namespace,
    when using a variable for the namespace name itself.

    Calling the namespace proc, or*updating* the namespace variable works ok. What bites me is how to*read* the namespace variable.

    As shown in the code below, I can read the namespace variable by combining
    it with the 'set' command.
    My question is if there is another way to read the namespace variable.


    Sample code:
    # --------------------------------------------------------------------------------
    # The example namespace
    namespace eval myns {
    variable myvar 42
    proc myproc {} {
    return "Hello world!"
    }
    }

    # Call namespace proc using string literal 'myns'
    puts "myns::myproc = [myns::myproc]"
    puts "::myns::myproc = [::myns::myproc]"

    # Read namespace variable using string literal 'myns'
    puts "myns::myvar = $myns::myvar"
    puts "::myns::myvar = $::myns::myvar"

    set NS_NAME myns

    What about this:

    % set ::${NS_NAME}::myvar
    42
    % ::${NS_NAME}::myproc
    Hello world!

    To get access, you may also enjoy "namespace which":
    % set varName [namespace eval $NS_NAME {namespace which -variable myvar}] ::myns::myvar
    % set $varName
    42

    % set cmdName [namespace eval $NS_NAME {namespace which -command myproc}] ::myns::myproc
    % $cmdName
    Hello world!

    Sorry, I did not understand all your examples, but this is IMHO
    conformant to your question.

    Take care,
    Harald

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Schelte@21:1/5 to [email protected] on Mon Aug 25 23:01:44 2025
    On 25/08/2025 22:34, [email protected] wrote:
    puts "myns::myvar = [set [namespace eval ::$NS_NAME {set ::${NS_NAME}::myvar}]"
    puts "myns::myvar = [set [namespace eval $NS_NAME {namespace which -variable myvar}]]

    As mentioned in my other response, that can be simplified to:

    puts "myns::myvar = [namespace eval $NS_NAME {set myvar}"

    My "real" question is if there is a "shorter" form for reading the variable.

    Depending on how much you need to use the variable, you can do:

    namespace upvar $NS_NAME myvar mynsvar
    puts "myns::myvar = $mynsvar"
    set mynsvar 43
    # Or set ${NS_NAME}::myvar 43
    puts "myns::myvar = $mynsvar"


    Schelte

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Schelte@21:1/5 to saito on Mon Aug 25 22:56:22 2025
    On 25/08/2025 21:20, saito wrote:
    # this works
    % puts "::NS_NAME::myvar  = [namespace eval ::$NS_NAME {set ::${NS_NAME}::myvar}]"

    It works, but it is very convoluted. Within the namespace there is no
    need to use a fully qualified variable name. So you could just do:

    % puts "::NS_NAME::myvar = [namespace eval $NS_NAME {set myvar}]"

    # this works
    % puts "::NS_NAME::myvar  = [eval {set ::${NS_NAME}::myvar}]"
    Here, there is no need for the eval:

    % puts "::NS_NAME::myvar = [set ::${NS_NAME}::myvar]"

    Which in fact is one of the options the OP already mentioned.


    Schelte

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Harald Oehlmann@21:1/5 to All on Tue Aug 26 09:22:43 2025
    Am 25.08.2025 um 22:34 schrieb [email protected]:

    Harald Oehlmann <[email protected]> posted:

    Am 25.08.2025 um 20:56 schrieb [email protected]:
    Hi,

    In the example code below, I try to access a proc and a variable in a namespace,
    when using a variable for the namespace name itself.

    Calling the namespace proc, or*updating* the namespace variable works ok. >>> What bites me is how to*read* the namespace variable.

    As shown in the code below, I can read the namespace variable by combining >>> it with the 'set' command.
    My question is if there is another way to read the namespace variable.


    Sample code:
    # --------------------------------------------------------------------------------
    # The example namespace
    namespace eval myns {
    variable myvar 42
    proc myproc {} {
    return "Hello world!"
    }
    }

    # Call namespace proc using string literal 'myns'
    puts "myns::myproc = [myns::myproc]"
    puts "::myns::myproc = [::myns::myproc]"

    # Read namespace variable using string literal 'myns'
    puts "myns::myvar = $myns::myvar"
    puts "::myns::myvar = $::myns::myvar"

    set NS_NAME myns

    What about this:

    % set ::${NS_NAME}::myvar
    42
    % ::${NS_NAME}::myproc
    Hello world!

    To get access, you may also enjoy "namespace which":
    % set varName [namespace eval $NS_NAME {namespace which -variable myvar}] >> ::myns::myvar
    % set $varName
    42

    % set cmdName [namespace eval $NS_NAME {namespace which -command myproc}]
    ::myns::myproc
    % $cmdName
    Hello world!

    Sorry, I did not understand all your examples, but this is IMHO
    conformant to your question.

    Take care,
    Harald


    Thank you both for your answers.

    With my examples, I tried to show that *setting* a namespace variable can be done
    using basically the same syntax with either using a string literal ('myns') or a variable ($NS_NAME):

    set myns::myvar 42
    set ${NS_NAME}::myvar 42

    And *getting* a namespace variable when using a string literal ('myns') is also straight-forward:

    puts "myns::myvar = $myns::myvar"

    Anyhow, *getting* a namespace variable when using a variable ($NS_NAME)
    seems to require either 'set', 'namespace eval' or 'namespace which' (or a combination):

    puts "myns::myvar = [set ${NS_NAME}::myvar]"
    puts "myns::myvar = [eval {set ::${NS_NAME}::myvar}]"
    puts "myns::myvar = [set [namespace eval ::$NS_NAME {set ::${NS_NAME}::myvar}]"
    puts "myns::myvar = [set [namespace eval $NS_NAME {namespace which -variable myvar}]]

    My "real" question is if there is a "shorter" form for reading the variable.

    BR,
    Johan
    Well, you need two rounds of variable resolution.
    For me, the following two are my favorites:
    If the variable should be accessed from the outside as value:
    [set ${NS_NAME}::myvar]
    If something should be done with the variable, this might be cleaner:
    namespace eval $NS_NAME {do something with $myvar}

    You may also consider using an object with tcloo. THen, you have more
    options here.
    Also, an access function is common.
    Normally, you don't want to expose the inside of a namespace to the
    outside.If you "just" want a variable store, dicts and arrays may be
    helpful.

    Take care,
    Harald

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to [email protected] on Wed Aug 27 21:48:18 2025
    [email protected] <[email protected]d> wrote:

    Yes, you are right, I probably don't want to expose the inside of a
    namespace to the outside.

    I have also learned that using a variable for namespace names may not
    be such a brillant idea that I first thought of. Sticking to
    hardcoded names makes the code cleaner, IMHO.

    Unless you are planning on building a generic "namespace inspector"
    that has to work for any given namespace, it is often best to simply
    use hard coded namespaces. Make the names meaningful to your codebase
    and don't worry about trying to "fake" something like a C pointer to
    get access to the internals.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Harald Oehlmann@21:1/5 to All on Thu Aug 28 10:30:05 2025
    Am 27.08.2025 um 20:13 schrieb [email protected]:

    Harald Oehlmann <[email protected]> posted:

    Am 25.08.2025 um 22:34 schrieb [email protected]:

    Harald Oehlmann <[email protected]> posted:

    Am 25.08.2025 um 20:56 schrieb [email protected]:
    Hi,

    In the example code below, I try to access a proc and a variable in a namespace,
    when using a variable for the namespace name itself.

    Calling the namespace proc, or*updating* the namespace variable works ok. >>>>> What bites me is how to*read* the namespace variable.

    As shown in the code below, I can read the namespace variable by combining
    it with the 'set' command.
    My question is if there is another way to read the namespace variable. >>>>>

    Sample code:
    # --------------------------------------------------------------------------------
    # The example namespace
    namespace eval myns {
    variable myvar 42
    proc myproc {} {
    return "Hello world!"
    }
    }

    # Call namespace proc using string literal 'myns'
    puts "myns::myproc = [myns::myproc]"
    puts "::myns::myproc = [::myns::myproc]"

    # Read namespace variable using string literal 'myns'
    puts "myns::myvar = $myns::myvar"
    puts "::myns::myvar = $::myns::myvar"

    set NS_NAME myns

    What about this:

    % set ::${NS_NAME}::myvar
    42
    % ::${NS_NAME}::myproc
    Hello world!

    To get access, you may also enjoy "namespace which":
    % set varName [namespace eval $NS_NAME {namespace which -variable myvar}] >>>> ::myns::myvar
    % set $varName
    42

    % set cmdName [namespace eval $NS_NAME {namespace which -command myproc}] >>>> ::myns::myproc
    % $cmdName
    Hello world!

    Sorry, I did not understand all your examples, but this is IMHO
    conformant to your question.

    Take care,
    Harald


    Thank you both for your answers.

    With my examples, I tried to show that *setting* a namespace variable can be done
    using basically the same syntax with either using a string literal ('myns') >>> or a variable ($NS_NAME):

    set myns::myvar 42
    set ${NS_NAME}::myvar 42

    And *getting* a namespace variable when using a string literal ('myns') is >>> also straight-forward:

    puts "myns::myvar = $myns::myvar"

    Anyhow, *getting* a namespace variable when using a variable ($NS_NAME)
    seems to require either 'set', 'namespace eval' or 'namespace which' (or a combination):

    puts "myns::myvar = [set ${NS_NAME}::myvar]"
    puts "myns::myvar = [eval {set ::${NS_NAME}::myvar}]"
    puts "myns::myvar = [set [namespace eval ::$NS_NAME {set ::${NS_NAME}::myvar}]"
    puts "myns::myvar = [set [namespace eval $NS_NAME {namespace which -variable myvar}]]

    My "real" question is if there is a "shorter" form for reading the variable.

    BR,
    Johan
    Well, you need two rounds of variable resolution.
    For me, the following two are my favorites:
    If the variable should be accessed from the outside as value:
    [set ${NS_NAME}::myvar]
    If something should be done with the variable, this might be cleaner:
    namespace eval $NS_NAME {do something with $myvar}

    You may also consider using an object with tcloo. THen, you have more
    options here.
    Also, an access function is common.
    Normally, you don't want to expose the inside of a namespace to the
    outside.If you "just" want a variable store, dicts and arrays may be
    helpful.

    Take care,
    Harald


    Yes, you are right, I probably don't want to expose the inside of a namespace to the outside.

    I have also learned that using a variable for namespace names may not be such a brillant idea that I first thought of.
    Sticking to hardcoded names makes the code cleaner, IMHO.

    Thanks again for all input.

    There is nothing wrong wrong your approach.

    Double resolution be the "set" command looks ugly (there is nothing
    set), but often a great tool. It is usable at any time where you have a variable name (or part of it) in a variable.

    But a tcl pbject might be a point to look to.

    Take care,
    Harald

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