VBScript Classes part 1. Why?
For a long time in my programming career I ignored classes. Certainly back in the days of QBasic they weren’t supported (though the good old goto/gosub was!), I guess I had a fleeting tryst with them during the AmigaOS days where they had some use – mainly for creating custom objects to exchange data with the OS itself, but still, I never really got the point.
Lately though it seems I can’t do a thing without them – I guess I finally understand what they are all about, but it certainly wasn’t through reading books and internet sites – I’ve never seen a good explanation of them in print, something I hope to change below.
So, first, why would you need class, and what is it?
Simply, a class is an encapsulation of code – much like a function or subroutine, but, where functions and subs do one thing, a class is a container of lots of functions and subs, plus private variables etc. It’s like a whole independent mini script within a script.
makes sense? no? Let me try with an example.
Imagine in your super, world-ending script you have a function which tracks something, like the number of times it’s been called:
Function iNumberOfTimesCalled counter=counter+1 iNumberOfTimesCalled=counter End Function
Now of course, you’re going to have to set counter to be a script level variable, otherwise it will get flushed every time you call the routine, and it will never return more than 1.
Dim counter Function iNumberOfTimesCalled counter=counter+1 iNumberOfTimesCalled=counter End Function wscript.echo iNumberOfTimesCalled wscript.echo iNumberOfTimesCalled
So this is all good – every time we call iNumberOfTimesCalled it will return an incremental number. Yes, I know there are a lot of other ways of doing this, but bare with me..
What happes though if we have another function which tracks something, and unfortunately we used the same system wide variable to track its progress? You could argue that we should simply know what variable does what, but in the case of long scripts, or in the case where you’re trying to make modular, reusable code, that might not be so obvious – for example:
Dim counter Function iNumberOfTimesCalled counter=counter+1 iNumberOfTimesCalled=counter End Function Function iLastIndex counter=counter+1 iLastIndex=counter End function WScript.Echo iNumberOfTimesCalled WScript.Echo "last Index",iLastIndex WScript.Echo iNumberOfTimesCalled
Now you can see things are getting confused. We’re using the same tracking variable in two unrelated routines.
The solution to this is classes. They let us encapsulate the entire scope of a set of routines in one place, with no chance of leakage etc. I’ll cut to the chase and show you my example written as a set of classes:
Dim counter : counter = 99 Dim tc: Set tc = New timescalled Dim li: Set li = New lastindex Class timescalled Private counter Public Function iNumberOfTimesCalled counter=counter+1 iNumberOfTimesCalled=counter End Function End Class Class lastindex Private counter Public Function iLastIndex counter=counter+1 iLastIndex=counter End Function End Class WScript.Echo "Counter :",counter WScript.Echo "Times Called :", tc.iNumberOfTimesCalled WScript.Echo "Last Index :", li.iLastIndex
You can see there’s a little more work involved, but if you run this, you’ll find that none of the “counter” variables interact at all. That’s what we were trying to achieve. You can take the “LastIndex” class out of one script and put it in any other without fear of collisions (as long as the class name is unique).
One final point on this primer – note at the top of this example where we define our class?:
dim tc: set tc = new timescalled
We create a Reference to the class by setting it to a variable. Of course, there’s no reason why there has to be only one reference to any named class – yes, you can have as many as you like, you can even have a whole array of them.
In my next entry on Classes, I’ll talk about the other cool stuff you can do with them, but I truly believe for the average VBS hack, encapsulation leading to reuse is what they are made for. If you look at my AutoDomain script, you’ll see most of it is a bunch of included classes (which get used in many other scripts as well), meaning I get complete code reuse from my ini file handling class, system analysis class, ActiveDirectory class and on.
Until next time, happy coding!