Hi Mike,
One useful tip (if you don't already know it) is how to organize your functions. I learned this from my betters (Stan, Jim, Kirby (and of course Tony)) over the years, and use it all the time myself.
In WinBatch, the functions (UDFs and UDSs) must be defined first, at the top of your script - but this can be a nuisance, since you must scroll past these already completed blocks of code in order to get to the code you are working on. So, we use this structure:
;-------------------------------------------------------------------------------
;dosumting.wbt - runs every Fri by TaskSched
;Purpose: Does [this and this and this] in order to solve [this problem]
;Written: 210822
;Last updated:
; - 210825 - NEW udfDoSummat added because... well, just because
;ToDos:
;Do this and this
;Also add this asap
;-------------------------------------------------------------------------------
gosub udfs
a line of code
a line of code
_name = udfDoSummat('fred')
a line of code
a line of code
EXIT
:udfs ;============================================
#DEFINEFUNCTION udfDoSummat(_bob) ;-----------------------------------
if _bob == 'fred' return 'sam'
else return 'bob'
#ENDFUNCTION ;udfDoSummat ----------------------------------------------
Return ;udfs ========================================
Did you notice the gosub udfs ? Simple idea but so helpful... And the top comments... only use what will be helpful to you. Short scripts (50-70 lines) might only need one or two lines up top - but trust me: you really do want to record why you wrote the script. If you're like me, three years from now you'll thank yourself.
Another thing that I do (don't know if it's good practice or not) is to name my variables with an _underscore as the first character - just because it then becomes very easy to search through the code for any specific variable. Suppose you want to name your variable "message" - searching for _message will not locate every time you used the message() command, nor will it find other vars that include "message" in their name (such as _prevMessage, or _nextMessage, or etc.
It is also important (as your code grows larger) to remember the difference between UDFs and UDSs... (again, forgive me if you already know). UDFs are closed systems - they know nothing outside themselves except what you pass into them, and anything done inside them is isolated from teh rest of the code except those values you pass back out. In other words, any variables you create inside the function disappear when the function is completed - so they don't remain behind to clutter your global namespace (i.e. list of variables used). UDSs work similarly to functions, except that they have full access to everything outside them, and any variables they create remain behind (unless they are explicitly dropped via the drop() command).
One final tip: for longer programs (and I've written many over 2000 lines) modularize your code where possible. A finished program should be easy to read years later:
goSub UDFs
goSub SetupEnv
goSub GetCurrentIP
if _location == 'home'
goSub homeStuff
else
goSub workStuff
endif
EXIT
:SetupEnv ;------------------------------------
;do a bunch of stuff
Return ;SetupEnv ------------------------------
:homeStuff ;-----------------------------------
;do a bunch of stuff
Return ;homeStuff -----------------------------
:workStuff ;-----------------------------------
;do a bunch of stuff
Return ;workStuff -----------------------------
:UDFs ;----------------------------------------
#DEFINEFUNCTION etc etc etc
#END FUNCTION
Return ;UDFs ----------------------------------
The structure below is also super-useful - it starts a program and keeps it running forever, until something in your code stops it.
_end = timeAdd(timeYmdHms(), `0000:00:00:3:00:00`)
while 1
goSub doThisThing
goSub doThatThing
goSub doAnotherThing
if timeYmdHms() > _end then terminate(1, `MyApp`, `MyApp just finished after running for 3 hours`)
endwhile
EXIT
:doThisThing
Return ;doThisThing
:doThatThing
etc
And learn to use arrays - they are very helpful.
_arrList = arrayize('jim@email.com|jim.pdf, doug@email.com|doug.pdf, sandy@email.com|sandy.pdf')
for _n = 0 to arrInfo(_arrList, 6)-1 ;-1 b/c arrInfo returns a 1-based number, but arrays are zero-based
_job = _arrList[_n]
_arrTmp = arrayize(_job, '|')
_eml = _arrTmp[0]
_pdf = _arrTmp[1]
udfSendEmail(_eml, _pdf)
next