• Re: namespace upvar outside a proc?

    From Andreas Leitgeb@21:1/5 to Robert Heller on Sat Jun 10 16:15:19 2023
    At Sat, 10 Jun 23 15:33:08 GMT [email protected] wrote:
    I want to use a variable in a namespace (containing configuration information) in
    several other namespaces. While the man page says namespace upvar
    works within proceedures, it appears to work outside them as well:

    namespace eval n1 {set v(a) aaa}
    namespace eval n2 {namespace upvar ::n1 v v}
    set n2::v(a)

    returns aaa

    Is there a simpler way to do this that I'm missing, or should the man page >> for upvar mention it works outside proc definitions as well as inside them?

    Maybe it was designed merely for procedures, and the effect seen
    here is just an "accident" ...

    If that is *not* the case, the wording in the docs ought to be changed.


    Robert Heller <[email protected]> wrote:
    You don't reallyto use namespace upvar:
    namespace eval n1 {}
    set n1::v(a) aaa
    set n1::v(a)
    returns aaa

    Robert, I think you mis-read the question.
    Dave requested the value of n2::v(a), not n1::v(a)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Heller@21:1/5 to [email protected] on Sat Jun 10 15:43:46 2023
    At Sat, 10 Jun 23 15:33:08 GMT [email protected] wrote:


    I want to use a variable in a namespace (containing configuration information) in
    several other namespaces. While the man page says namespace upvar
    works within proceedures, it appears to work outside them as well:

    namespace eval n1 {set v(a) aaa}
    namespace eval n2 {namespace upvar ::n1 v v}
    set n2::v(a)

    returns aaa

    Is there a simpler way to do this that I'm missing, or should the man page for upvar mention it works outside proc definitions as well as inside them?

    You don't reallyto use namespace upvar:

    namespace eval n1 {}

    set n1::v(a) aaa


    set n1::v(a)

    returns aaa


    Dave B





    --
    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 [email protected]@21:1/5 to All on Sat Jun 10 15:33:08 2023
    I want to use a variable in a namespace (containing configuration information) in
    several other namespaces. While the man page says namespace upvar
    works within proceedures, it appears to work outside them as well:

    namespace eval n1 {set v(a) aaa}
    namespace eval n2 {namespace upvar ::n1 v v}
    set n2::v(a)

    returns aaa

    Is there a simpler way to do this that I'm missing, or should the man page
    for upvar mention it works outside proc definitions as well as inside them?

    Dave B

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et99@21:1/5 to All on Sat Jun 10 18:44:56 2023
    On 6/10/2023 6:28 PM, et99 wrote:
    On 6/10/2023 9:15 AM, Andreas Leitgeb wrote:
    At Sat, 10 Jun 23 15:33:08 GMT [email protected] wrote:
    I want to use a variable in a namespace (containing configuration information) in
    several other namespaces. While the man page says namespace upvar
    works within proceedures, it appears to work outside them as well:

    namespace eval n1 {set v(a) aaa}
    namespace eval n2 {namespace upvar ::n1 v v}
    set n2::v(a)

    returns aaa

    Is there a simpler way to do this that I'm missing, or should the man page >>>> for upvar mention it works outside proc definitions as well as inside them?

    Maybe it was designed merely for procedures, and the effect seen
    here is just an "accident" ...

    If that is *not* the case, the wording in the docs ought to be changed.


    Robert Heller <[email protected]> wrote:
    You don't reallyto use namespace upvar:
    namespace eval n1 {}
    set n1::v(a) aaa
    set n1::v(a)
    returns aaa

    Robert, I think you mis-read the question.
    Dave requested the value of  n2::v(a), not n1::v(a)

    While not the official documentation, in Ashok's
    Tcl book, section 12.5.1.3 on namespace upvar, he says,

    "When the command is invoked outside a procedure,
    LOCALVAR names a namespace variable in the namespace
    in which the command is invoked."

    And then he provides the examples to back that up.

    Also, he uses

    namespace upvar NAMESPACE ?NSVAR LOCALVAR …?

    as his template.

    One statement in the manual that seems to indicate this is,

    The command *namespace upvar $ns a b* has the same behaviour as *upvar 0 ${ns}::a b*

    But that is confusing to me, since I don't know what 0 is for a level, while #0 is
    used to mean global level. Did they leave off the # also?



    Wait, I think a level of 0 means the current level, since:

    % proc foo {} {set b bbb; upvar 0 b b2; puts $b; puts $b2}
    % foo
    bbb
    bbb


    seems to allow for an alias in the same proc, so maybe that
    manual is correct, though I couldn't find anywhere that they
    explicitly talked about level 0.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et99@21:1/5 to Andreas Leitgeb on Sat Jun 10 18:28:25 2023
    On 6/10/2023 9:15 AM, Andreas Leitgeb wrote:
    At Sat, 10 Jun 23 15:33:08 GMT [email protected] wrote:
    I want to use a variable in a namespace (containing configuration information) in
    several other namespaces. While the man page says namespace upvar
    works within proceedures, it appears to work outside them as well:

    namespace eval n1 {set v(a) aaa}
    namespace eval n2 {namespace upvar ::n1 v v}
    set n2::v(a)

    returns aaa

    Is there a simpler way to do this that I'm missing, or should the man page >>> for upvar mention it works outside proc definitions as well as inside them?

    Maybe it was designed merely for procedures, and the effect seen
    here is just an "accident" ...

    If that is *not* the case, the wording in the docs ought to be changed.


    Robert Heller <[email protected]> wrote:
    You don't reallyto use namespace upvar:
    namespace eval n1 {}
    set n1::v(a) aaa
    set n1::v(a)
    returns aaa

    Robert, I think you mis-read the question.
    Dave requested the value of n2::v(a), not n1::v(a)

    While not the official documentation, in Ashok's
    Tcl book, section 12.5.1.3 on namespace upvar, he says,

    "When the command is invoked outside a procedure,
    LOCALVAR names a namespace variable in the namespace
    in which the command is invoked."

    And then he provides the examples to back that up.

    Also, he uses

    namespace upvar NAMESPACE ?NSVAR LOCALVAR …?

    as his template.

    One statement in the manual that seems to indicate this is,

    The command *namespace upvar $ns a b* has the same behaviour as *upvar 0 ${ns}::a b*

    But that is confusing to me, since I don't know what 0 is for a level, while #0 is
    used to mean global level. Did they leave off the # also?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to [email protected] on Sun Jun 11 02:57:21 2023
    et99 <[email protected]> wrote:
    Wait, I think a level of 0 means the current level, since:

    % proc foo {} {set b bbb; upvar 0 b b2; puts $b; puts $b2}
    % foo
    bbb
    bbb

    seems to allow for an alias in the same proc, so maybe that
    manual is correct, though I couldn't find anywhere that they
    explicitly talked about level 0.

    This seems consistent with the documentation for uplevel (which is
    where the "level" argument is defined):

    If level is an integer then it gives a distance (up the
    procedure calling stack) to move before executing the command.
    If level consists of # followed by a number then the number
    gives an absolute level number.

    For an integer it is an "offset" of sorts. And a "level" of zero would reasonably mean go up a distance of zero (or, in other words, stay in
    the current context).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Sun Jun 11 13:53:52 2023
    Perhaps the man page text can be changed to say:

    This command arranges for zero or more local variables in the
    current procedure or current namespace to refer to variables
    in the specified namespace ...

    Dave B

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From greg@21:1/5 to All on Mon Jun 12 22:50:44 2023
    et99 schrieb am Sonntag, 11. Juni 2023 um 03:45:00 UTC+2:


    seems to allow for an alias in the same proc, so maybe that
    manual is correct, though I couldn't find anywhere that they
    explicitly talked about level 0.

    https://wiki.tcl-lang.org/page/upvar
    Link to another variable in the same execution frame

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From greg@21:1/5 to All on Mon Jun 12 23:12:52 2023
    ...
    Is there a simpler way to do this that I'm missing, or should the man page for upvar mention it works outside proc definitions as well as inside them?

    Dave B

    In
    TIP 276: Specify and Unify Variable Linking Commands

    https://core.tcl-lang.org/tips/doc/trunk/tip/276.md

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