Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>First off, Tcl command names can have spaces in. Or in fact nearly any other character; the only ones you have to be careful of are <code>:</code>s because <code>::</code> is a namespace separator, and a leading <code>::</code> is fine as it just means that it is a fully-qualified name.</p> <p>Because of that, <code>::postLayRep1||mainTableView sendToLoads</code> is a legal but unusual command name. If you put the name in a variable, you can then use a read from that variable just as if it is a command name:</p> <pre><code>$theVariableContainingTheCommandName </code></pre> <p>Using an array element is nothing special in this regard.</p> <p>Now, if you want to instead treat that as a script, you pass it to <code>eval</code> like this:</p> <pre><code>eval $theVariableContainingTheScript </code></pre> <p>The real problem you're having is that you instead are doing:</p> <pre><code>eval {$theVariableContainingTheScript} </code></pre> <p>That is defined to be <em>exactly</em> identical to doing just:</p> <pre><code>$theVariableContainingTheScript </code></pre> <p>That won't ever do what you appear to want. Looking at the code that's causing you the problem:</p> <pre><code>if { [catch {eval {$mCallBackCont(insert) [namespace tail $this] $type $name $n $redraw}} e] } { error "Wrong number of arguments for the procedure \"$mCallBackCont(insert)\". Should be \"table type name num redraw\"." } </code></pre> <p>In this case, the value in the variable has to be the name of a command, and not just a script fragment. The simplest fix for you is to create an alias which binds in the extra arguments:</p> <pre><code>interp alias {} callBackForInsert {} ::postLayRep1||mainTableView sendToLoads </code></pre> <p>Then you can use <code>callBackForInsert</code> just as if it was the combination of calling <code>::postLayRep1||mainTableView</code> with the first argument <code>sendToLoads</code>. It's effectively a named partial application. Alternatively, you can use a helper procedure:</p> <pre><code>proc callBackForInsert args { return [uplevel 1 {::postLayRep1||mainTableView sendToLoads} $args] } </code></pre> <p>But that's both uglier and slower in this simple case. Better in 8.6 is to use <code>tailcall</code>:</p> <pre><code>proc callBackForInsert args { tailcall ::postLayRep1||mainTableView sendToLoads {*}$args } </code></pre> <p>But that is still slower than an alias because of the overhead of the extra stack frame manipulation.</p> <hr> <p>However, the <em>nicest</em> fix if you can is to alter the library so it uses the callback like this (assuming Tcl 8.5 or later):</p> <pre><code>if { [catch {eval {{*}$mCallBackCont(insert) [namespace tail $this] $type $name $n $redraw}} e] } { error "Wrong number of arguments for the procedure \"$mCallBackCont(insert)\". Should be \"table type name num redraw\"." } </code></pre> <p>Which can be simplified to:</p> <pre><code>if { [catch {{*}$mCallBackCont(insert) [namespace tail $this] $type $name $n $redraw} e] } { error "Wrong number of arguments for the procedure \"$mCallBackCont(insert)\". Should be \"table type name num redraw\"." } </code></pre> <p>A good rule of thumb is that there's hardly ever a reason to use <code>eval</code> in modern Tcl code; a <code>{*}</code>-expansion is virtually always closer to what is intended.</p> <p>If you're stuck with 8.4 but can change the library code, you can do this instead:</p> <pre><code>if { [catch {eval $mCallBackCont(insert) {[namespace tail $this] $type $name $n $redraw}} e] } { error "Wrong number of arguments for the procedure \"$mCallBackCont(insert)\". Should be \"table type name num redraw\"." } </code></pre> <p>This uses the fact that <code>eval</code> will concatenate its arguments before feeding them back through the Tcl script evaluation engine.</p> <hr> <p>The combination of aliases, expansion, <code>tailcall</code> and (not used in this answer) ensembles lets you do awesome stuff with very little code, allowing complicated remixing of arguments without having to load yourself down with lots of helper procedures.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload