Version 1 of variable vs global

Updated 2020-03-04 15:21:26 by sebres

This example illustrates difference of precedence by resolving of not fully-qualified namespace variables in procedure using variable and global.

variable v "::v"
namespace eval ::P {
  proc tv {h n} { puts -nonewline [format "%.4s %4s from %-7s ->   " $h $n [namespace current]]; catch { $h $n; set v } res; puts $res }
  variable v "[namespace current]::v";
  namespace eval C {
    variable v "[namespace current]::v";
    proc tv {h n} [info body ::P::tv]
  }
}
proc test {ns} {
  puts "  ================  test $ns   === "
  namespace eval $ns {
    tv global   P::v
    tv variable P::v
    tv global   v
    tv variable v
  }
}

puts "================== without ::P::P::v and ::P::C::P::v =================="
test ::P::C; test ::P

puts "================== create ::P::P::v and ::P::C::P::v =================="
foreach n {::P::C::P ::P::P} {
  namespace eval $n {  variable v "[namespace current]::v" }
}

test ::P::C; test ::P

results in:

================== without ::P::P::v and ::P::C::P::v ==================
  ================  test ::P::C   ===
glob P::v from ::P::C  ->   ::P::v
vari P::v from ::P::C  ->   can't define "P::v": parent namespace doesn't exist
glob    v from ::P::C  ->   ::v
vari    v from ::P::C  ->   ::P::C::v
  ================  test ::P   ===
glob P::v from ::P     ->   ::P::v
vari P::v from ::P     ->   can't define "P::v": parent namespace doesn't exist
glob    v from ::P     ->   ::v
vari    v from ::P     ->   ::P::v
================== create ::P::P::v and ::P::C::P::v ==================
  ================  test ::P::C   ===
glob P::v from ::P::C  ->   ::P::v
vari P::v from ::P::C  ->   ::P::C::P::v
glob    v from ::P::C  ->   ::v
vari    v from ::P::C  ->   ::P::C::v
  ================  test ::P   ===
glob P::v from ::P     ->   ::P::v
vari P::v from ::P     ->   ::P::P::v
glob    v from ::P     ->   ::v
vari    v from ::P     ->   ::P::v

See Also

variable
Declares and optionally sets variables in a namespace.
global
Access global variables or variables in a namespace.
set
Reads or assigns a value to a variable.
namespace upvar
Gives a variable in one namespace a name at the current level.
upvar
Links a variable at some higher level to a variable at the current level.