title: Using upvar when procedures are invoked by channel events and retrieving the value to which a pointer points?
body: <p>I have two questions about the following code.</p>
  <ol>
  <li><p>Is it possible to use <code>upvar</code> in <code>ReadLine</code> when it is invoked by the channel event? In experimenting with <code>upvar</code>, I used this exact same scenario except <code>ReadLine</code> was invoked directly rather than through the event; and it worked fine.  It fails as is because <code>state($sock)</code> is not recognized. Is a different <code>#n</code> value needed or does it have to be global? It tried <code>#2</code> and that threw an error that is was a bad value.</p>
  </li>
  <li><p>In procedure <code>ReadLine</code> I tried to make a pointer to <code>$state($sock)</code> such that it points to the list itself. In experimenting, it worked fine for <code>lappend $sptr $op</code>, for example; but failed on <code>set row [lindex $sptr 0]</code> because <code>$sptr</code> is <code>state(1)</code>. However, it does work if use <code>set</code>, such as <code>set row [lindex [set $sptr] 0]</code>. Why is this? Is there another method of getting the value to which a pointer is pointing? Is attempting to use pointers in Tcl a bad idea?  Does the fact that the body of procedures are transformed into bytecode representation mean using pointers doesn't make much difference?</p>
  </li>
  </ol>
  <p>Thank you.</p>
  <pre><code>proc ClientConnect {sock client_ip client_port} {    
     if {![info exists state($sock)]} {set state($sock) {1}}; 
     chan configure $sock -buffering line -blocking 0 -translation crlf
     chan event $sock readable [list ReadLine $sock]
  }
  
  proc ReadLine {sock} {
  
    # The #1 in upvar is to first caller, which is ClientConnect.
    # Make a ptr to the array list rather than retrieving it each reference,
    # such that $sptr is state($sock)'s list.
  
    upvar #1 state r
    set sptr r($sock)
    puts stdout &quot;x: [lindex $r($sock) 0]&quot;; #Fails to recognize state.
    set row [lindex [set $sptr] 0]
  }
  </code></pre>
  <p>The experimenting code that appears to work properly:</p>
  <pre><code>proc ReadLine {sock} {
   upvar #1 row rtemp; #Recognizes row.
   set r rtemp($sock)
   lappend $r &quot;new&quot;
  
   set line &quot;Content-length: 247899&quot;
   if { [string first &quot;Content-length:&quot; $line] == 0 } { lappend $r [string trim [string range $line 16 end]] }
  
   lappend $r &quot;help&quot;
   puts [lindex [set $r] 3]; #Output is: 247899.
   puts $rtemp($sock); #Output is: 1 GET new 247899 help.
  }
      
  proc do {sock} {
    set row($sock) {1 GET}
    ReadLine $sock
  }
  
  set sock 1
  do $sock
  </code></pre>