0

I'm sure I'm just being stupid but would you please tell me how to get access to $name inside the namespace in order to set variable n to $name? I can only find how to do this when the procedure is in the namespace but not the other way 'round. No matter what I try, this errors stating no such variable name. Thank you.

proc getNS {name} {
  namespace eval ns::$name {
    variable n $name
  }
}

This works but isn't really an answer unless the answer is simply that it cannot be done directly. Got it from this SO question. Bryan Oakley gave the answer but used [list set...] instead of [list variable...] and that will fail if there is a global variable of the same name. (It will modify the global rather than creating a new variable in the namespace.) It may have been different, of course, in 2009 when that answer was provided.

proc getNS {name} {
  namespace eval ns::$name [list variable n $name]
  namespace eval ns::$name {
    variable a abc
  }
}
set n xyz
getNS WEBS
chan puts stdout "ns n: $ns::WEBS::n; a $ns::WEBS::a, global n: $n"
# => ns n: WEBS; a: abc; global n: xyz

Gary
  • 2,393
  • 12
  • 31

1 Answers1

2

You can just use set with a fully qualified variable name that uses the desired namespace:

proc getNS {name} {
    namespace eval ns::$name {} ;# Create namespace if it doesn't already exist                                                                                                                                                                  
    set ns::${name}::n $name
}

getNS foo
puts $ns::foo::n ;# foo

Another way is to use uplevel to refer to the scope of the proc that calls namespace eval:

proc getNS {name} {
    namespace eval ns::$name {
        set n [uplevel 1 {set name}]
    }
}
Shawn
  • 47,241
  • 3
  • 26
  • 60