Paul Randall schrieb:
Quote:
> In a recent response to Sigheart's request for help removing carriage
> returns (http://www.developersdex.com/asp/mes...1825&r=6670690),
> ekkehard.horner included a vbscript that seemed a little strange, and
> stated:
>
> If you like the idea of schizo scripts, say so, and I will discuss more
> elaborate
> strategies to create them.
>
> I'm not sure whether I like the idea of schizo scripts, but I definitely
> would like a discussion on the subject. I'm sorry I didn't read your post
> in detail when you first posted it. In an ideal world, a programmer knows all about the problem to solve and
has the knowledge, skills, and tools to write the program. That program
will consist of exactly the lines of code that are necessary to do the task:
Add one line and you are on the way to maintenance problems caused by code
bloat, delete one line and the script will fail to solve the problem.
In the real world you have to work with incomplete specifications. You
may not know every nook and cranny of the (new version of the) language
your boss asked you to use. Necessary technologies may be unfamiliar. I'm
interested in strategies/methods/practices to make the process of gathering
knowledge/skills on the fly - while coping with your given task - more
efficient.
When I started programming, books and teachers recommended "think/plan
before you code". That was fine in a fairly stable environment; nowadays
their advice is: put your (partial) knowledge into code as soon as
possible - to make sure your assumptions are correct and to avoid blind
alleys early.
So how do you start a new project on monday if it is not a trivial variation
of the project you finished successfully on friday? The high-tech approach
of an experienced Java programmer may involve an eclipse project created
from a template with UML diagrams and unit tests. A humble VBScript newbie
should
decide on a project name (PrjName)
create a subdirectory PrjName
create two empty files
PrjName.notes (to gather all info pertaining to the project)
PrjName.vbs
Instead of this very low-tech approach (everybody should be able to that
without further study), a programmer with more knowledge, skills, and tools
will call CreateProjectWizard.vbs with suitable parameters to get a
project folder containing subdirectories for data, test scripts, and
(automatically generated) documentation as well as some more files with
more content derived from carefully crafted templates.
Now it can't be avoided that the first script of a person learning VBScript
looks like
c:\MyFirstScript.vbs
WScript.Echo "yes, I can!"
Unfortunately, that is *not* an efficient way to increase your knowledge,
skills, and tool set. You just wasted time on doing/practicing something
you should never do again:
putting a file at a stupid location
using a silly name
writing a script that does not solve a problem
writing unstructured code (the mess is hidden, but still there)
writing unsafe code
That's why your second script should look like:
000 c:\WhereEver\PrjName\PrjName.vbs
001 ''# PrjName.vbs - short description of the script's purpose
002 ' <preamble: author, copyright, ...>
003
004 ''# Config
005 Option Explicit
...
006
007 ''# Globals
...
010
011 ''# Dispatch
...
017 WScript.Quit doMain()
018
019 ''# Main Functions
020
021 ''= doMain - short description of the functions's purpose
022 Function doMain()
023 Dim nErrCode : nErrCode = 0 ' assume no error
024 WScript.Echo WScript.ScriptName & "::doMain()"
025 WScript.Echo "not implemented yet."
026 doMain = nErrCode
027 End Function
Now we have
a file at a suitable location (000 - assuming you wrote something
reasonable instead of WhereEver)
a good name (001 - assuming you came up with a short and significant
name for the project [my choice of "sigheart" is a deplorable makeshift])
at least the intend of providing a solution to a problem (001, 021 -
this is a necessary base for thinking about/discussing the most important
question of code quality: does the program solve the problem
correctly
reliably
efficiently
within the given constraints of time and money
so that it can be maintained/improved easily
structure:
one place for (hardcoded) configurational information (004)
one place for the (few) global variables (007)
just one [effective] statement of top level code (017)
(sub)tasks neatly contained/caged in Functions or Subs (022...)
the first step to safe code: Option Explicit (005)
That's a bit more work than just writing
024 WScript.Echo WScript.ScriptName & "::doMain()"
025 WScript.Echo "not implemented yet."
(the equivalent to the HelloWorld script). What do we get for the extra
effort with regard to
strategies/methods/practices to make the process of gathering
knowledge/skills on the fly - while coping with your given task -
more efficient?
We can use the dispatch section to concentrate on the various (kinds
of) sub problems/tasks we encounter when we stepwise improve our
understanding of the problem (specification)
plans/ideas of how to solve the problem as a whole resp. its
sub tasks - or even jobs that are not directly connected to
the main goal - e.g. my
012 WScript.Quit lineNumberFile()
...
029 ''= lineNumberFile - prepend line numbers to text file lines
030 Function lineNumberFile()
031 Dim nErrCode : nErrCode = 0 ' assume no error
...
046 lineNumberFile = nErrCode
047 End Function
implementation (trying out more than one way to do a task)
confidence in the code written
All that can be done in an orderly fashion. You don't have to litter
a temp directory with lots of independent scripts or to (de)comment or
to edit lines (thereby loosing the old version which may turn out
better with hindsight) all over the places in an unstructured sequence
of 200 LOCs.
The dispatch method (comment/move) is definitely not rocket science.
If you can do arguments and Select Case (perhaps after some experiments
using the KISS approach) your script could look like:
007 ''# Globals
008 Dim goFS : Set goFS = CreateObject( "Scripting.FileSystemObject" )
009 Dim goWAN : Set goWAN = WScript.Arguments.Named
010
011 ''# Dispatch
012 WScript.Quit SelectCaseDispatch()
...
238 ''= SelectCaseDispatch - use arguments and Select Case to dispatch
239 Function SelectCaseDispatch()
240 Dim nErrCode : nErrCode = 0 ' assume no error
241 WScript.Echo WScript.ScriptName & "::SelectCaseDispatch()"
242
243 Dim sAct : sAct = "FrsTest"
244 If goWAN.Exists( "act" ) Then sAct = goWAN( "act" )
245 Select Case LCase( sAct )
246 Case "frstest"
247 nErrCode = doFrsTest()
248 Case "sectest"
249 nErrCode = doSecTest()
250 Case Else
251 WScript.Echo "no act", sAct
252 WScript.Echo "try frstest or sectest"
253 nErrCode = 2
254 End Select
255
256 SelectCaseDispatch = nErrCode
257 End Function
258
259 ''= doFrsTest - just to show that SelectCaseDispatch works
260 Function doFrsTest()
261 Dim nErrCode : nErrCode = 0 ' assume no error
262 WScript.Echo WScript.ScriptName & "::doFrsTest()"
263 doFrsTest = nErrCode
264 End Function
265
266 ''= doSecTest - just to show that SelectCaseDispatch works
267 Function doSecTest()
268 Dim nErrCode : nErrCode = 0 ' assume no error
269 WScript.Echo WScript.ScriptName & "::doSecTest()"
270 doSecTest = nErrCode
271 End Function
sample output:
C:\wis\_vbs\0506\dev\forum\Sigheart
cscript sigheart.vbs /act:sectest
sigheart.vbs::SelectCaseDispatch()
sigheart.vbs::doSecTest()
There is a even more elaborate version in the pipeline ...
To explain my (feeble) schizo joke: the last/production version of your script
will have a stable personality (all LOCs contribute to the solving of the
problem), but to get there, it pays to have written (a) script(s) that can
do different/heterogenous things in an orderly (and predictable) way.