Published: Wednesday, May 02, 2001
Object References in VBScript (Variables and Values in VBScript, Part 3)
By Bill Wilkinson
| Part 3 in a Three-Part Series |
|
This article is the third part in a three-part series. Part 1 of this series,
Variables and Values in VBScript, examined how
VBScript treated scalar variables: Strings and primitive data types. The second part,
Variables, Values, and Arrays, delved deeper
under the covers and looks at how VBScript handles both single and multi-dimensional arrays.
This third and final part examines object references and how VBScript handles copying objects and arrays!
|
Understanding Object References
In the previous articles in this series (part one and
part two) we looked at the basics of how variables and values
are implemented in VBScript (and, with minor variations, in JScript) and of how VBScript represents and
uses arrays. As noted in the previous articles, in VBScript, all variables are always of the same kind or
type, a VARIANT (which is in turn an OLE-defined structure). And a VARIANT instance always occupies 16 bytes
of memory but only uses what is needed. The first two bytes of the VARIANT always indicate what the other
14 bytes are holding, and different types of data use pre-defined portions of those 14 bytes.
Now, let's consider an object in VBScript. For example, whenever you run any of the following code you are
creating an object.
Set dict = Server.CreateObject("Scripting.Dictionary")
Set fso = Server.CreateObject("Scripting.FileSystemObject")
Set conn = Server.CreateObject("ADODB.Connection")
Set rs = conn.Execute("SELECT * FROM someTable")
...
|
The first three examples there even say so, explicitly. The last example shows that some methods on one kind of
object can return a new object themselves! "But wait a minute!" you cry, "How can 14 bytes hold an entire
ADODB.RecordSet object or an entire Scripting.Dictionary object?" Time to go back and
re-read part one of this series. To quote: "For all except the primitive
data types ... the VARIANT contains a pointer to the actual data!"
So all those variables above actually contain pointers to the various objects.
Okay, so what happens when you copy one of those variables to another variable? Perhaps a short demonstration is
in order:
<HTML><BODY>
<%
Set d1 = Server.CreateObject("Scripting.Dictionary")
d1.Add "first", "added via d1.add"
Set d2 = d1
d2.Add "second", "this via d2.add"
Response.Write "from d1('second') we get: " & d1("second") & "<P>"
Response.Write "from d2('first') we get: " & d2("first") & "<P>"
%>
</BODY></HTML>
|
If you do that, you will see, as output:
from d1('second') we get: this via d2.add
from d2('first') we get: added via d1.add
Hopefully, you understand that this is pretty clear evidence that both
d1 and d2 refer to exactly the same object! Changes made by either variable affect the
object that is referenced by either variable. Once again, it is important to understand that a variable that you
might think of as being an object is actually just a reference to an object. This is not strange. Other
computer languages have the same constructs. Java, for example, also allows only references to objects. And
C++ normally works with pointers and references to objects (though you can work directly with a static
or automatic object in that somewhat strange and wonderful language).
A Limitation of VBScript (and ActiveX) Objects
Simply put, the one thing you can not do with objects is copy them! Oh, there are a handful of ActiveX
objects that have copy or clone methods available, but those are special cases, implemented
by the objects themselves. There is simply no intrinsic way in ActiveX or VBScript (or JScript or JavaScript) to
copy an object.
Actually, this makes sense. Let's consider a Scripting.File object, for example. You use such an
object, say, to open a given file in exclusive mode, so only you can write to it. If you copied that object,
then what could happen in any reasonable way? You certainly couldn't have two objects such that each thinks it
has exclusive control of the same file! So VBScript (and ActiveX) simply doesn't implement any default copy or
clone operation. (The default in other languages, such as C++, is to simply copy the bytes in the object without
paying attention to context. Which is why most C++ programmers are forced to write "copy constructors" for all
but the simplest classes.) So it's pretty tempting to say that this VBScript "limitation" is actually a feature!
In Part 2 we'll examine how VBScript works with copying arrays.
Read Part 2