Variable Scope

Technical support and scripting issues

Moderators: Dorian (MJT support), JRL

Post Reply
JimmyBoy
Newbie
Posts: 6
Joined: Mon Feb 08, 2010 2:09 pm

Variable Scope

Post by JimmyBoy » Sun Jun 17, 2018 4:32 pm

Hi,

I am aware of LOCALVARS to set the scope of variables created after the command.

// Global
Let>LOCALVARS=0
Let>MyGlobalVar=GlobalValue

// Local
Let>LOCALVARS=1
Let>MyLocalVar=LocalValue

However, as mentioned in a previous post from some years back, this can become somewhat troublesome when nested calls are being made and changing LOCALVARS.

Would it not make a lot more sense to have a command that will just define a variable instance as local instead of having to deal with the management of LOCALVARS. eg.

Let>MyGlobalVar=GlobalValue
Local>MyLocalVar=LocalValue

Failing this, I see the need for me to implement some additional functionality that handles LOCALVARS, which I dont really want to do, but the current implementation is a little problematic. Something like SRT>SetVariableScopeToGlobal, SRT>SetVariableScropeToLocal and RestoreVariableScope. These subs would essentially manage a stack (array) that push's/pop's the scope.

Pseudo Code:
GoSub>SetVariableScopeToGlobal
Gosub>SubA

SRT>SubA
GoSub>SetVariableScopeToLocal
Let>MyVarName=Local1
Gosub>SubB
Gosub>RestoreVariableScope
END

SRT>SubB
GoSub>SetVariableScopeToLocal
Let>MyVarName=Local2
Gosub>RestoreVariableScope
END

SRT>SetVariableScopeToGlobal
PUSH current scope to stack
Let>LOCALVARS=0
END

SRT>SetVariableScropeToLocal
PUSH current scope to stack
Let>LOCALVARS=1
END

SRT>RestoreVariableScope
POP scope from stack
Let>LOCALVARS=(from stack)
END

User avatar
PepsiHog
Automation Wizard
Posts: 511
Joined: Wed Apr 08, 2009 4:19 pm
Location: Florida

Re: Variable Scope

Post by PepsiHog » Sun Jul 08, 2018 3:16 pm

Hello,

What is the question here? When you localize it means you don't want to effect the macro outside of the current routine. Maybe you want to reuse the same var names without effecting the same vars value outside the current subroutine. If you need to use the result, then you need to release the localized command and then create your result that you do want the rest of the macro to use or don't localize.

Here is an example of using the same var name after localizing and then releasing it and creating a result for the entire macro.

Otherwise, you are just defeating yourself.

Code: Select all

let>NoEffect=This won't change.
GoSub>LocalTest
mdl>%NoEffect%%crlf%%IsResult%

srt>LocalTest
let>Localvars=1
let>NoEffect=Not outside this srt.
let>Localvars=0
let>IsResult=what I am trying to accomplish here. (%NoEffect%)  

END>LocalTest
This is useful for keeping the macro readable and easily followed by not recreating the same var with a different name. Constantly changing your var names gets very confusing. Plus sometimes the vars name is just the perfect name for understanding what it's purpose is.

I think I learned something just posting this for you. Or I clarified it for myself. Neat. Thanks.
Windows 7

PepsiHog. Yep! I drink LOTS of Pepsi (still..in 2021) AND enjoy programming. (That's my little piece of heaven!)

The immensity of the scope of possibilities within Macro Scheduler pushes the user beyond just macros!

User avatar
PepsiHog
Automation Wizard
Posts: 511
Joined: Wed Apr 08, 2009 4:19 pm
Location: Florida

Re: Variable Scope

Post by PepsiHog » Sun Jul 08, 2018 4:57 pm

After I study your example, I am starting to think you want a switch outside of the subroutine to turn on/off the localizing effect. That's pretty simple to do, if that is what you are looking for.

Code: Select all

let>MySwitch=1
let>NoEffect=This won't change.
GoSub>LocalTest
mdl>%NoEffect%%crlf%%IsResult%



srt>LocalTest
let>Localvars=%MySwitch%
let>NoEffect=Not outside this srt.
let>Localvars=0
let>IsResult=what I am trying to accomplish here. (%NoEffect%)  

END>LocalTest
Just change the value of MySwitch to 0/1. Then recall the subroutine.
Windows 7

PepsiHog. Yep! I drink LOTS of Pepsi (still..in 2021) AND enjoy programming. (That's my little piece of heaven!)

The immensity of the scope of possibilities within Macro Scheduler pushes the user beyond just macros!

JimmyBoy
Newbie
Posts: 6
Joined: Mon Feb 08, 2010 2:09 pm

Re: Variable Scope

Post by JimmyBoy » Thu Oct 11, 2018 11:12 pm

Thanks for your reply PepsiHog and sorry for a delayed reply.

I was not very clear in my original post.

What I want is to use the same named variable in multiple routines and also restore the state of LOCALVARS to its previous value, not manually hard set it. To my mind, a sub should not be changing anything outside of itself which has an affect on how future code may run (ie, I should not run a sub and then find the LOCALVARS value has changed).

I could write something like this ;

Code: Select all

Let>LOCALVARS=0
Let>i=0
Gosub>Sub1
SRT>Sub1
  Let>LOCALVARS=1
  Let>i=1
End>Sub1
The above code works as expected, insofar as the variable 'i' remains at 0 in the code before the call to Sub 1. The issue with the above code is, the routine has changed the state of LOCALVARS. I could put a Let>LOCALVARS=0 at the end of the Sub, but what if LOCALVARS=1 before the call? or vice versa. Essentially I want to restore the state of LOCALVARS to the value it was at before the call.

I wrote the following code which does what I want. You can see the first message box displays LOCALVARS = 1 (LOCALVARS was changed by the sub calls), whereas the second message displays (LOCALVARS = 0). The LOCALVARS state was changed by the subs (sub4, sub5, sub6), but it was also restored to its original state.

Code: Select all

VBSTART
  
  Dim variableScope(128)
  variableScopeCount=0

  Function saveCurrentVariableScope(currentScope)
    variableScope(variableScopeCount)=currentScope
    variableScopeCount=variableScopeCount+1
  End Function

  Function restoreVariableScope
    If variableScopeCount <= 0 Then
        restoreVariableScope=variableScope(0)
    Else
        variableScopeCount=variableScopeCount-1
        restoreVariableScope=variableScope(variableScopeCount)
    End if
  End Function
  
VBEND

Let>LOCALVARS=0
Let>i=0
Gosub>Sub1
MessageModal>%i%, LOCALVARS = %LOCALVARS%

Let>LOCALVARS=0
Let>i=0
Gosub>Sub4
MessageModal>%i%, LOCALVARS = %LOCALVARS%


SRT>Sub1
  Let>LOCALVARS=1
  Let>i=1
  Gosub>Sub2
END>Sub1

SRT>Sub2
  Let>LOCALVARS=1
  Let>i=2
  Gosub>Sub3
END>Sub2

SRT>Sub3
  Let>LOCALVARS=1
  Let>i=3
END>Sub3

SRT>Sub4
  Gosub>setVariableScopeToLocal
  Let>i=4
  Gosub>restoreVariableScope
  Gosub>Sub5
END>Sub4

SRT>Sub5
  Gosub>setVariableScopeToLocal
  Let>i=5
  Gosub>restoreVariableScope
  Gosub>Sub6
END>Sub5

SRT>Sub6
  Gosub>setVariableScopeToLocal
  Let>i=6
  Gosub>restoreVariableScope
END>Sub6

SRT>setVariableScopeToLocal

  VBRun>saveCurrentVariableScope,%LOCALVARS%
  Let>LOCALVARS=1

END>setVariableScopeToLocal

SRT>setVariableScopeToGlobal

  VBRun>saveCurrentVariableScope,%LOCALVARS%
  Let>LOCALVARS=0

END>setVariableScopeToGlobal

SRT>restoreVariableScope

  VBEval>restoreVariableScope,LOCALVARS

END>restoreVariableScope

Post Reply
Sign up to our newsletter for free automation tips, tricks & discounts