"Error in Tcl script
Error: can't read "shift": no such variable
OK Skip Message Stack Trace"
The stack contents is as follows:
can't read "shitf": no such variable
while executing
"puts "\n shift: $shitf""
(procedure "change_RZ_hist_aint" line 18)
invoked from within
"change_RZ_hist_aint"
invoked from within
".button_aint.menu invoke active"
("uplevel" body line 1)
invoked from within
"uplevel #0 [list $w invoke active]"
(procedure "tkMenuInvoke" line 47)
invoked from within
"tkMenuInvoke .button_aint.menu 1
"
(command bound to event)
Thnak you in advance for your help.
Maura
*************************************************************************************************
* Tcl stuff
*
*************************************************************************************************
proc mf_ui {root args} { # outermost proc #
global plot
global events_info
global hist_info
global euler_info
global aint
global old_aint
global shift
set aint 1.e10
set old_aint 1.e10
puts "\n AINT: $aint"
.......................................
........................................
button $base.button_undo -text "<<" -command undo_canvas
button $base.button_redo -text ">>" -command redo_canvas
menubutton $base.button_aint -text "AINT" -menu
$base.button_aint.menu -relief raised
set m [menu $base.button_aint.menu -tearoff 1]
$m add radio -label 1.e10 -variable aint -value 1.e10 -command
change_RZ_hist_aint
$m add separator
$m add radio -label 1.e12 -variable aint -value 1.e12
-command change_RZ_hist_aint
button $base.button_asrt -text "1:1" -command ToBeDone
grid $base.button_undo -in $base.frame_undoredo -row 1 -column 1
-sticky nesw
grid $base.button_redo -in $base.frame_undoredo -row 1 -column 2
-sticky nesw
grid $base.button_aint -in $base.frame_undoredo -row 1 -column 3
-sticky nesw
grid $base.button_asrt -in $base.frame_undoredo -row 1 -column 4
-sticky nesw
proc change_RZ_hist_aint {} { # proc that generates the error #
global hist_info
global aint
global old_aint
global shift
if {[catch {check_hist_aint_option} result] != 0} {
tk_messageBox -default ok -type ok -icon error -message "AINT
does not apply to the current histogram"
exit 1
} else {
puts "\n previous AINT value: $old_aint"
puts "\n current AINT value: $aint"
if {$old_aint != $aint} {
delete_hist_bar;
set line [get_hist_bar_shift $old_aint $aint ]
scan $line {%d} shift
puts "\n shift: $shitf"
set hist_info(binmax) [expr $hist_info(binmax) + $shift]
set hist_info(binmin) [expr $hist_info(binmin) + $shift]
if { $ihis == 0 } {
draw_hist_bar 75 621 36 12 $hist_info(binmax)
$hist_info(binmin) $hist_info(max) $hist_info(min)
}
if { $ihis == 1 } {
draw_hist_bar 134 621 51 12 $hist_info(binmax)
$hist_info(binmin) $hist_info(max) $hist_info(min)
}
}
set old_aint $aint
}
}
*************************************************************************************************
* C stuff
*
*************************************************************************************************
Tcl_CreateCommand( interp, "check_hist_aint_option",
check_hist_aint_option_cb,
(ClientData)NULL,
(Tcl_CmdDeleteProc *)NULL );
Tcl_CreateCommand( interp, "get_hist_bar_shift",
get_hist_bar_shift_cb,
(ClientData)NULL,
(Tcl_CmdDeleteProc *)NULL );
/***********************************************************************************************/
/* verify the AINT rescaling option is available for the currently
active histogram */
/*
*/
static int
check_hist_aint_option_cb( ClientData clientData,
Tcl_Interp *interp,
int argc, char *argv[] ) {
int i;
if ( hg.active_ <= 0 ){
Tcl_SetResult( interp,
"Histogram not active !",
TCL_STATIC );
return TCL_ERROR;
}
i = -1;
while ((++i < Length_of_AINT_histo_ID) && (hg.hid_ !=
AINT_histo_ID[i])) ;
if (i >= Length_of_AINT_histo_ID) {
Tcl_SetResult( interp,
"Renormalization option unavailable for the current
histogram !",
TCL_STATIC );
return TCL_ERROR;
}
return TCL_OK;
}
/**********************************************************************************************/
/* Calculates colors_bar shift from ratio of old and new rescaling
factors */
/*
*/
static int
get_hist_bar_shift_cb( ClientData clientData,
Tcl_Interp *interp,
int argc, char *argv[] ) {
double old_norm;
double new_norm;
double Ratio;
double Dshift;
int shift;
if ( argc != 3 ) {
Tcl_SetResult( interp,
"wrong # args: should be \"get_hist_bar_shift
<old_aint> <new_aint>\"",
TCL_STATIC );
return TCL_ERROR;
}
old_norm = strtod( argv[1], NULL );
new_norm = strtod( argv[2], NULL );
Ratio = (double) new_norm/old_norm;
Dshift = (double) log10((double) new_norm/old_norm);
shift = (int) log10((double) new_norm/old_norm);
sprintf( tclres_buffer, "%d", shift);
return TCL_OK;
}
***********
* NOTE *
***********
most of the C lines are redundant and will be dropped. But they were
useful to me to track the data type conversion and make sure the right
data type was returned to the Tcl interpreter.
> "Error in Tcl script
> Error: can't read "shift": no such variable
> OK Skip Message Stack Trace"
Run the program and read that error again, letter by letter. You
mistyped it here to say what you thought it says, but what it actually
says will tell you exactly what the problem is.
> The stack contents is as follows:
>
> can't read "shitf": no such variable
> while executing
> "puts "\n shift: $shitf""
> (procedure "change_RZ_hist_aint" line 18)
Notice the actual spelling of the global variable, versus the spelling
you used in the puts command.
Couple problems here:
1) Please read the error message, instead of assuming Tcl is doing something
strange. It looks like you made a typo.
2) There is no such thing as declaring a variable in Tcl. The global
command does not declare a variable, it creates a lookup link from one stack
frame to another stack frame.
3) Variables get created when you assign them a value. No where in what you
posted do you set a value to shift or shitf.
--
+--------------------------------+---------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+
You're right. Nothing is returned to the Tcl interpreter because I
forgot the statement:
Tcl_SetResult( interp, tclres_buffer, TCL_VOLATILE );
in the C routine "get_hist_bar_shift".
Now it works. So I can try to improve its behaviour.
Thank you,
Maura
> can't read "shitf": no such variable
> while executing
> "puts "\n shift: $shitf""
> (procedure "change_RZ_hist_aint" line 18)
> invoked from within
> "change_RZ_hist_aint"
> invoked from within
> ".button_aint.menu invoke active"
> ("uplevel" body line 1)
> invoked from within
> "uplevel #0 [list $w invoke active]"
> (procedure "tkMenuInvoke" line 47)
> invoked from within
> "tkMenuInvoke .button_aint.menu 1
that's shitf-ull of errors!
;-)
--
Donald Arseneau as...@triumf.ca
set hist_info(binmax) [expr $hist_info(binmax) + $shift]
set hist_info(binmin) [expr $hist_info(binmin) + $shift]
vs
set hist_info(binmax) [expr {$hist_info(binmax) + $shift } ]
set hist_info(binmin) [expr {$hist_info(binmin) + $shift } ]
not only it is safer if you get used to them, but it is in fact faster.
and i would move the global variables and global array into an
namespace and make a wrapper like:
histinfo::shift max $shift
looks better imho, but that is just flavour i guess.
sample code for histinfo::shift:
::namespace eval histinfo {
::variable max
::set max 0 ;# default
::variable min
::set min 0 ;# default
## incr varName i
##
## varName - one of { min max }
## i - any number
::proc shift { varName i } {
::return [set $varName [::expr {[set $varName] + $i}]]
}
## set - like the normal set
## set varName ?newValue?
::proc set { varName args } {
::variable $varName
::if {0<[::llength $args]} then {
::set $varName [::lindex $args 0]
}
::return [::set $varName ]
}
}