Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Look Ma, I can redefine global variables even with Option Explicit active -- but why?

Tags:

vbscript

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.

like image 887
TheBlastOne Avatar asked Jun 26 '13 09:06

TheBlastOne


1 Answers

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.

like image 132
MC ND Avatar answered Nov 15 '22 05:11

MC ND