clock quirk

D. McC 2009/01/01: Something strange just happened when I was running supposedly simple "clock" commands from a procedure (using Tcl 8.5.5 on Puppy Linux 4.1.1). The commands, individually, work right:

 % set startdate 2009/01/14
 2009/01/14

 % set scanno [clock scan $startdate -format "%Y/%m/%d"]
 1231862400

 % set quant 1
 1

 % set unit year
 year

 % set addo [clock add $scanno $quant $unit]
 1263398400

 % set formato [clock format $addo -format "%Y/%m/%d"]
 2010/01/14

But then I put the same commands into a proc, and I got an error message:

 % proc recur {startdate unit quant} {
        set scanno [clock scan $startdate -format "%Y/%m/%d"]
        set addo [clock add $scanno $quant $unit]
        set recurdate [clock format $addo -format "%Y/%m/%d"]
         return $recurdate
 }
 % recur 2009/01/14 1 year
 can't read "flag": no such variable

Running the proc from within a GUI in an app I'm trying to develop, I get these details in the error dialog:

 can't read "flag": no such variable
 can't read "flag": no such variable
    while executing
 "list CLOCK badSwitch $flag"
    (procedure "::tcl::clock::add" line 37)
    invoked from within
 "clock add $scanno $quant $unit"
    (procedure "recur" line 55)
    invoked from within
 "recur $startdate $unit $quant"
    (procedure "markok" line 10)
    invoked from within
 "markok .li(1)"
    invoked from within
 ".li(1).ok invoke"
    ("uplevel" body line 1)
    invoked from within
 "uplevel #0 [list $w invoke]"
    (procedure "tk::ButtonUp" line 22)
    invoked from within
 "tk::ButtonUp .li(1).ok"
    (command bound to event)

Can anybody tell me what's going on here and how to fix it? If so, thanks in advance!


MG The problem with your code is that you're passing the "unit" and "quant" args to your code in the wrong order, so it's doing

  clock add $scanno year 1

instead of "1 year". The code for clock add checks each pair of arguments to see whether the first arg in the pair is a number; if so, it assumes it's a number of units, and if not it assumes it's one of the flags (-gmt, -locale or -timezone, by the looks of it) that the command takes. If it's not one of those flags, it raises an error, but it does so using an incorrect variable name (it refers to it as $flag, but it's actually called $a), so a "no such variable" error gets thrown. I'll report it on SF in a moment if it's not already there.


D. McC Interesting--I didn't know the order of args specified in the proc would make any difference. (I put "unit" first because the complete proc (when done) was intended to deal with expressions like "Sun 1,3" for the first and third Sundays in a month, not only things like "1 year" which can go straight to "clock add" as is. I guess "Sun 1,3" will have to be changed to "1,3 Sun," and I don't think it will go to "clock add" as is!)

OK, here's the revised incomplete proc, and sure enough, it doesn't raise an error. Thanks!

 proc recur {startdate quant unit} {
        set scanno [clock scan $startdate -format "%Y/%m/%d"]
        set addo [clock add $scanno $quant $unit]
        set recurdate [clock format $addo -format "%Y/%m/%d"]
        return $recurdate
 }

 % set startdate 2009/01/14
 2009/01/14

 % set quant 1
 1

 % set unit year
 year

 % recur $startdate $quant $unit
 2010/01/14