how to declare a variable globally which is used only in proc
Asked Answered
O

3

5

i am having a following code:

proc testList {setupFile ""} {
  if {$setupFile == ""} {
    set setupFile location
  }
}
proc run {} {
  puts "$setupFile"
}

I am getting syntax error. I know if i declare the setupFile variable outside the proc i.e in the main proc then i can append it with namespace say ::65WL::setupFile to make it global but not getting how to do that if a variable itself is defined in the proc only.

Odonnell answered 16/4, 2012 at 18:10 Comment(0)
S
4

Tcl variables that are not local to a specific procedure run need to be bound to a namespace; the namespace can be the global namespace (there's a special command for that) but doesn't need to be. Thus, to have a variable that is shared between two procedures, you need to give it an exposed name:

proc testList {{setup_file ""}} {
  # Use the 'eq' operator; more efficient for string equality
  if {$setup_file eq ""} {
    set setup_file location
  }
  global setupFile
  set setupFile $setup_file
}
proc run {} {
  global setupFile
  puts "$setupFile"
}

Now, that's for sharing a full variable. There are some other alternatives provided you only want to share a value. For example, these two possibilities:

proc testList {{setup_file ""}} {
  if {$setup_file eq ""} {
    set setup_file location
  }
  # Create a procedure body at run-time
  proc run {} [concat [list set setupFile $setup_file] \; {
    puts "$setupFile"
  }]
}
proc testList {{setup_file ""}} {
  if {$setup_file eq ""} {
    set setup_file location
  }
  # Set the value through combined use of aliases and a lambda term
  interp alias {} run {} apply {setupFile {
    puts "$setupFile"
  }} $setup_file
}

There are more options with Tcl 8.6, but that's still in beta.

Steeplejack answered 16/4, 2012 at 18:36 Comment(0)
E
18

You can refer to the global namespace with ::.

proc testList {{local_setupFile location}} {
    # the default value is set in the arguments list.
    set ::setupFile $local_setupFile
}

proc run {} {
    puts $::setupFile
}
Express answered 16/4, 2012 at 18:53 Comment(0)
S
4

Tcl variables that are not local to a specific procedure run need to be bound to a namespace; the namespace can be the global namespace (there's a special command for that) but doesn't need to be. Thus, to have a variable that is shared between two procedures, you need to give it an exposed name:

proc testList {{setup_file ""}} {
  # Use the 'eq' operator; more efficient for string equality
  if {$setup_file eq ""} {
    set setup_file location
  }
  global setupFile
  set setupFile $setup_file
}
proc run {} {
  global setupFile
  puts "$setupFile"
}

Now, that's for sharing a full variable. There are some other alternatives provided you only want to share a value. For example, these two possibilities:

proc testList {{setup_file ""}} {
  if {$setup_file eq ""} {
    set setup_file location
  }
  # Create a procedure body at run-time
  proc run {} [concat [list set setupFile $setup_file] \; {
    puts "$setupFile"
  }]
}
proc testList {{setup_file ""}} {
  if {$setup_file eq ""} {
    set setup_file location
  }
  # Set the value through combined use of aliases and a lambda term
  interp alias {} run {} apply {setupFile {
    puts "$setupFile"
  }} $setup_file
}

There are more options with Tcl 8.6, but that's still in beta.

Steeplejack answered 16/4, 2012 at 18:36 Comment(0)
R
1

you can use uplevel, upvar and/or global

proc testList {{setupFile ""}} {
  if {$setupFile eq ""} {
    set setupFile location;
    uplevel set setupFile $setupFile;
  }
}
proc run {} {
  upvar setupFile setupFile;
  puts "$setupFile";
}

or

proc run {} {
  global setupFile;
  puts "$setupFile";
}

the first is prefered.

Religion answered 20/10, 2014 at 19:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.