Tutorial 3 - Programming tips

Top  Previous  Next

Source code for this project is supplied in the Tutorials folder (by default, within \Program Files\WhiskerControl).


Programming Tips

VB is a dirty language. It's quick and easy, but the flip side to this is that it is easy to write code that nearly does what you want. In fact, it is so easy to write bad code in VB, that many professional programmers will not touch it.


But – a little care can help you avoid some of the pitfalls.




Note the lines outside the subs in the code we saw above (Tutorial 2). These start with apostrophes, which shows that they are comments (they are ignored by Visual Basic, but they help the human reader understand what is going on). ALWAYS add comments to your code – one day soon, someone will try to work out what your program does (probably you) and it saves time if they can see what each bit is doing. It also makes it much easier to spot mistakes when you are debugging – if you have to look at the whole code to work out what a subroutine does, it is more difficult to see that it does the wrong thing! Code that is difficult to follow is almost worse than useless: most people learn this through experience – either through looking back at their own code, or trying to follow someone else's code.


A warning for Arachnid Users:


Arachnid offers the 'KillSwitch' function – after this has been called, the pipe cannot be executed, and the service function will not be called. In Whisker, you can ask for an event to be Cleared [i.e. ask the server not to generate any more] but the event might (conceivably) be have been generated before you ask: i.e. occur 'in the gap' between your client processing the event, and your 'Clear event' response. In general, this will virtually never occur, and it is easy to write clients that only respond to events that they expect.


However – people who wish to transfer tasks from Arachnid to Whisker should not rely on this, and there are occasions when it could even be likely. For example, if we set up a display document that had two adjacent objects, and put them on the screen, each with their own response: a touch on the screen at the boundary could produce two different events almost simultaneously. The following code might then fail:


Private Sub Whisker_Event(ByVal EventMessage As String, ByVal Time As Long)

       Select Case EventMessage

               Case Box1: Whisker.DisplayBlank("Screen"): Call Correct

               Case Box2: Whisker.DisplayBlank("Screen"): Call Wrong

       End Select

End Sub


Relying on the DisplayBlank to prevent another eventmessage arriving is a problem: we might end up with both Correct and Wrong being called. How can we prevent this? The Whisker SDK provides functions to "ignore" events, which works in a similar way to Arachnid:






Once an event is Killed, then any message for that event will be ignored from that point on – note this is not the same as preventing these messages from being generated.


ClearEvents prevents messages being generated from a particular source (doesn't garauntee that none are in the queue).

KillEvent makes the library ignore any event with that name (no matter where it comes from) from that moment until ReviveEvent() is called.


In order to undo a message, call ReviveEvent(). To undo all Killed messages, call ReviveEvent with an empty string (Whisker.ReviveEvent("")).


Practice with the Debugger. It is useful and it is your friend!


Always type option explicit at the top of each module or form. This tells VB that you will declare (using a Dim, public or private statement) every variable before you use it. This means that you cant just invent a variable 'as you go'. This might sound like a rubbish idea but it means that you will never find that your program doesn't work because you've written TrailData = 3 instead of TrialData = 3. VB will notice the misspelling if you set option explicit, otherwise it will assume you want a new variable, and carry on happily


The VB Environment can be annoying. Two ways of making it better can be done on the ToolsOptions Dialog.


oSelect Environment, then check "Prompt to Save Changes" when a program starts. That way, you can save your program before you start it. This is handy -  if your program crashes, you don't lose everything.


oSelect Editor, and uncheck "Auto Syntax Check". This feature just pops up message boxes if you ever leave a line unfinished in your code (e.g. while looking something up. The most annoying feature ever invented.


Try to avoid reading BASIC 'as if it were English'. It isn't. The language has very  precise meaning, and you should always read its structure if you can. To test yourself: what will the following code do? (Debug.Print prints to the immediate window).


Dim A As Integer

For A = 1 To 3

If A = 1 Or 2 Then

       Debug.Print "Low"


       Debug.Print "High"

End If



Put the code into Form_Load and try it. Does it do what you expect? If not, why not? The answer is in the 'general tips files' folder.


Look at other people's code. Try to learn from it. If it is easy to understand, try to see why. There are three main ways of learning to code: by example, by example and by example…


Give your subroutines and variables sensible names. It is often a good idea to name your variables with names that show what type of data they refer to (e.g. iNumber for integers, strName for strings, txtATextBox for controls). Try to avoid the Variant data type (that is, declaring variables without giving them a data type) unless you have to. It's easier to debug code when you use data types.


Understand variable scope, and don't use global variables unless you have to. Learn about static variables.


If you write procedures that might be useful in lots of experiments, put them in a separate module. This can help you reuse your code.


Learn what you can about object oriented programming. It is (honestly) worth it!


Good Luck…