Execution contexts
The developers experienced in usage of the complied languages
such as C++, Delphi or Visual Basic know about the differences
between the global variables and local variables. With ASPC such
knowledge is very important because one of the major purposes of
ASPC is the adjustment of the variable scopes in the script files
during the translation to VB. In this chapter we will try to
illustrate this process for the users with no knowledge in the
compiled languages area.
Scripts (ASP pages and other active scripts).
VBScript supports code placed outside the bodies of any
functions/subs or class bodies (called global part of the
script). This is not true for VB and most of the compiled
languages. In a VBScript file this code is executed first and any
function calls happen only if this code invokes them. Every
variable or routine defined in the global part of the
script is accessible from all the functions and classes in this
script. Thus if you have some VBScript classes defined in an
include file you will be able to use every global variable from
their members.
See this little example:
<%
Dim a
a = "Blah"
Class C
Dim b
Public Sub ASub
Response.Write a & "<BR>
b ="A number" & rnd
End Sub
Public Sub BSub
Response.Write b & "<BR>"
End Sub
End Class
Dim cls
Set cls1 = New C
cls1.ASub
cls1.BSub
Set cls2 = New C
cls2.ASub
cls2.BSub
%>
The call to the ASub will print the content of variable a
because it is accessible for the member sub.
The operator New creates an instance of the class C.
Thus the class declaration is a source of multiply instances of
the class. If you create more instances of the same class call to
the ASub of any one of them will produce the same result
because they are using the same global variable, but BSub
uses a variable b which is declared as a class member. And
its value will be separate for every instance (Here rnd
function is used and the results will be random).
Up to this point everything looks well known - life scope of a
is the entire script. Scope of the b is the class
containing it. Thus life time of the variables is bound to the
script (a) and class instance (b).
|
If compiled to VB the same example will define two classes: Class C
and a class for the global part of the script. The name of
the second class will be selected automatically by the compiler or
can be set using the ClassName
directive.
The corresponding loader file generated by the compiler will have a
lines like these:
Dim proc
Set proc = Server.CreateObject("... the name of the class
...")
' Some initialization code
proc.ASPCExecuteClass
What this means? An instance of the class generated from the global
part of the script is created and a member Sub of this class is
called on it. In other words we have two different classes in the
compiled form and the global variables (and/or routines) from the
original ASP page are now members of this class. The class C remains
in different file and its instances will be created by the instance
of the other class - which packs the global part of the script. As
before every class including the class created from the global
part of the script may have multiply instances. Thus variable a
cannot be accessed in the same manner as in the script.
Suppose you have several concurrent requests to this page - then
several instances of the global class will be active in memory
thus variable one a will exist as member variable in every
one of them and it will be kept in different memory block.
Therefore ASPC needs to connect every instance of the global
class (class created by ASPC from the global part of the script)
with the instances of the class C created in its members. ASPC
does this connection for you but this means the variable s is no
longer global! Well everything looks ok - why should I care
about it? Using the DLLGlobal
directive you have a chance to make a variable declaration or
routine declaration true global declaration for the DLL created.
But this is not the same as in the script case. It can be used to
improve the performance but also may cause dangerous errors if you
are not aware what it means. The variable (or routine) declared
with DLLGlobal directive becomes global for the DLL and it is not
a member of any class - including the global class. Thus it will
not have any access/will not be accessible for the members of the
classes. And if in the original form of the page it has the same
scope as the other global routines and variables in the compiled
DLL its scope will be different. In the DLL its scope is the DLL
and life time of the variable is the life time of the DLL and not
of a particular class/page. In other words if you assign a value
to this variable this value will be visible to all the pages
currently using the DLL- no matter which one made the change. You
can think about these variables and routines as for the
Application object in ASP. They exist in one instance for all the
objects/pages implemented in the DLL. Therefore you should check
what variables are accessed from a routine before declaring it
DLLGlobal. If it uses any variables not passed as arguments to it
usage of the directive will not be appropriate. About the
variables the situation is similar - they will be accessible for
all the objects currently active in memory. This is ideal for the
constants but for the variables it will be good only if their
values do not depend on the particular request.
|