tags:

views:

97

answers:

3
proc foo {param} {
  namespace eval foo_ns {
     uplevel {set foo_ns::x $param }
  }
}

This just looks ugly.

[upvar] will not work, because it can't link to 'param'.

Thanks.

Code from answers does not work (tclsh8.4)

-------------------------------------------

% proc bar {param} {
    namespace eval foo_ns {
      uplevel [list set foo_ns::x $param]
    }
  }
% bar 123
can't read "param": no such variable

-------------------------------------------

% proc foo {param} {
    set ::foo_ns::x $param
}
% foo 123
can't set "::foo_ns::x": parent namespace doesn't exist
+4  A: 

What is wrong with:

proc foo {param} {
    set ::foo_ns::x $param
}

In my test, it seems to accomplish the same objective.

Update: Thanks To K0re for pointing this out. Before calling foo, you need to define the name space:

namespace eval ::foo_ns {}
Hai Vu
# tclsh8.4 % proc foo {param} { set ::foo_ns::x $param } % foo 123 can't set "::foo_ns::x": parent namespace doesn't exist
name
formatting looks ugly, however it ended up with:can't set "::foo_ns::x": parent namespace doesn't exist
name
@K0re: You will have to define the namespace prior to to calling foo: namespace eval ::foo_ns {}
Hai Vu
+1  A: 

Ok, you have two different problems. The first is that the namespace doesn't already exist; the second is that you need to write the code so that the variable is created/written in that namespace. Overall, this require only a tiny modification of Hai's code:

proc foo {param} {
    # Create the namespace if it doesn't already exist
    namespace eval ::foo_ns {}
    # Set the variable in the namespace
    set ::foo_ns::x $param
}


As commentary on some of the problems you were having:

proc foo {param} {
  namespace eval foo_ns {
     uplevel {set foo_ns::x $param }
  }
}

This doesn't work because you are, effectively, saying the following: in the namespace "foo_ns", run the following code: at the top level of the stack, rung the following code: "set foo::x $param"

However, at the top level of the stack, the variable "param" has no value (its only defined within the procedure. You'll need to make sure it gets substitured beforehand. I'd include code that would work but, honestly, I'm afraid it will cause confusion with the actual answer to the question... so I'll leave it out.

RHSeeger
2nd code (the one I wrote before) works good.I just didn't liked the syntax - it's ugly.1st code looks better.Thanks.
name
I can't follow which code it is you don't like... but as long as you can get it to work and understand WHY, then it's all good :)
RHSeeger
+2  A: 

Namespaces and levels are two different things. You don't need uplevel for this problem.

Here's a simple solution that creates the namespace and sets the variable in one line:

proc foo {param} {
    namespace eval ::foo_ns [list set x $param]
}
Bryan Oakley