Here's one nice crazy discovery:
Option Explicit
ExecuteGlobal "Option Explicit: Dim TestVar: TestVar=41"
ExecuteGlobal "Option Explicit: TestVar=42"
MsgBox "TestVar=" & CStr (TestVar)
works as expected -- displays 42.
And:
Option Explicit
ExecuteGlobal "Option Explicit: TestVar: TestVar=41"
MsgBox "TestVar=" & CStr (TestVar)
yields "Undefined variable" in the ExecuteGlobal call since TestVar is not defined. OK.
What I do not understand is that this:
Option Explicit
ExecuteGlobal "Option Explicit: Dim TestVar: TestVar=41"
ExecuteGlobal "Option Explicit: Dim TestVar: TestVar=42"
MsgBox "TestVar=" & CStr (TestVar)
does not throw "Identifier redefined" in the second ExecuteGlobal
call, but displays 42 -- as if the Dim
in the second ExecuteGlobal
call wasn't present.
If you do the same with Class
declarations, everything works fine, i.e. you cannot redefine a class under any circumstances.
What the hell?
My question is: Why does ExecuteGlobal
allow me to redefine a global variable while a) ExecuteGlobal does forbid access to undeclared variables and b) class definitions are treated differently?
I do have a usecase that leads to this (generating source code at test runtime and executing it via ExecuteGlobal for some not-as-weird-as-you-might-expect reason), but the points I just made are valid enough without a description of the real-world secenario I think.
I came across this using QTP (HP QuickTest Professional), which uses the VisualBasic scripting host engine for script playback, but it is exactly the same situation in VB scripting host only.
The following code
Option Explicit
ExecuteGlobal "WSCript.Echo b "
will not fail. The context of the executeglobal doesn't know about the declared Option explicit. But
Option Explicit
ExecuteGlobal "Option Explicit : WSCript.Echo b "
fails with a runtime error. Everyting is working, but in a separate environment. And
Option explicit
Dim b
ExecuteGlobal "Option Explicit : WScript.Echo b "
Works as expected.
In the following code
Option Explicit
ExecuteGlobal "Option Explicit: Dim a : a = 1 : Dim a : a = 2"
you will get the redefined name error. And this is a compiler error, not a runtime error.
If, as indicated, you do the same with classes
Option Explicit
Class thisThing
End Class
ExecuteGlobal "class thisThing : End Class"
you get a runtime error, redefined name.
So, from your tests and these tests (and some more), it "seems" ExecuteGlobal generates a new context, work inside it while executing the passed code, and on exit, the context is merged with the original calling context.
So, to answer your questions:
a) Variables can be "redefined" if it is done in different contexts. Values of variables are merged.
b) ExecuteGlobal doesn't allow access to undefined variables if option explicit is used inside the ExecuteGlobal context.
c) A variable is a variable. Value can change on ExecuteGlobal, and it is merged on exit. But class redefinition is changing what something IS, not what somenthing contains.
I've not decompiled the VBScript engine, but this seems coherent with the observed behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With