Does "endlocal" close all instances of "setlocal"?

Microsoft Windows
Post Reply
PiotrMP006
Posts: 19
Joined: 2021-Sep-01, 10:57 am

Does "endlocal" close all instances of "setlocal"?

Post by PiotrMP006 »

Does "endlocal" close all instances of "setlocal"?

ex

Code: Select all

setlocal enabledelayedexpansion enableextensions
set name1=1

setlocal disabledelayedexpansion enableextensions
set name2=2

setlocal enabledelayedexpansion enableextensions
set name3=3

endlocal
OJBakker
Posts: 13
Joined: 2021-Jul-29, 7:06 am

Re: Does "endlocal" close all instances of "setlocal"?

Post by OJBakker »

Just add a few lines to your script and the answer is obvious.
Try the script below.
setlocal enabledelayedexpansion enableextensions
set name1=1
setlocal disabledelayedexpansion enableextensions
set name2=2
setlocal enabledelayedexpansion enableextensions
set name3=3
set name
endlocal
set name
endlocal
set name
User avatar
jesus2099
Posts: 2
Joined: 2023-Jul-25, 11:32 am

Re: Does "endlocal" close all instances of "setlocal"?

Post by jesus2099 »

Let me show the result as the previous answer left me hungry:

Code: Select all

@echo off
setlocal enabledelayedexpansion enableextensions
set name1=1
setlocal disabledelayedexpansion enableextensions
set name2=2
setlocal enabledelayedexpansion enableextensions
set name3=3
echo.
set name
endlocal
echo.
set name
endlocal
echo.
set name
Result:

Code: Select all


name1=1
name2=2
name3=3

name1=1
name2=2

name1=1

So the answer is endlocal does not close all instances of setlocal.
endlocal closes the most recent and non-ended setlocal.
User avatar
Simon Sheppard
Posts: 191
Joined: 2021-Jul-10, 7:46 pm
Contact:

Re: Does "endlocal" close all instances of "setlocal"?

Post by Simon Sheppard »

jesus2099 wrote: 2023-Jul-25, 11:35 am So the answer is endlocal does not close all instances of setlocal.
endlocal closes the most recent and non-ended setlocal.
Yes and it couldn't be any other way, it restores the whole environment including any values which you had overwritten:

Code: Select all

@Echo off
setlocal
set _demo=start
set _demo
setlocal
set _demo=midddle
set _demo
setlocal
set _demo=end
set _demo

endlocal
set _demo

endlocal
set _demo
and the output:

Code: Select all

_demo=start
_demo=middle
_demo=end
_demo=middle
_demo=start
Rekrul
Posts: 52
Joined: 2021-Aug-15, 11:29 pm

Re: Does "endlocal" close all instances of "setlocal"?

Post by Rekrul »

I'm just curious: How many of you use setlocal by itself and not paired with enabledelayedexpansion, or enableextensions?

It seems to me that the only real use for setlocal by itself is to be able to temporarily re-use variables. Which seems like a great way to confuse yourself and make debugging harder. I'd just prefer to use a different variable rather than keeping track of which version of a variable is in use.
User avatar
Simon Sheppard
Posts: 191
Joined: 2021-Jul-10, 7:46 pm
Contact:

Re: Does "endlocal" close all instances of "setlocal"?

Post by Simon Sheppard »

Rekrul wrote: 2023-Jul-27, 8:19 am I'm just curious: How many of you use setlocal by itself and not paired with enabledelayedexpansion, or enableextensions?
I start every script with

Code: Select all

@echo off
setlocal
Just as a matter of habit, even for scripts which don't (yet) contain any variables.
If you run a script from a CMD session and it sets variables without using Setlocal, then those variables stick around after the script finishes.
Run a few such scripts and you can have an environment filled with a mish mash of left-over variables, which is just messy.

Closing CMD and restarting a new session will clear them out.

Now you can easily imagine a situation where you are writing/debugging a script without Setlocal, editing and running it a few times until it works, then you shut everything down, go back the next day and it doesnt work.
Rekrul
Posts: 52
Joined: 2021-Aug-15, 11:29 pm

Re: Does "endlocal" close all instances of "setlocal"?

Post by Rekrul »

Simon Sheppard wrote: 2023-Jul-27, 11:43 am Just as a matter of habit, even for scripts which don't (yet) contain any variables.
If you run a script from a CMD session and it sets variables without using Setlocal, then those variables stick around after the script finishes.
Run a few such scripts and you can have an environment filled with a mish mash of left-over variables, which is just messy.
I have encountered this, but...

This is only really a problem in two situations:

1. Numeric variables which get incremented. If they're not set to zero by the script, and you run it again, it will start with the previous value.

2. Variables set as the result of user input. If the user just presses Enter, the previous value will be used.

In all other situations that I can think of at the moment, you wouldn't try to use a variable if it hasn't previously been set, unless you've just made a mistake and forgotten to set it.

For numeric variables, I make it a habit to set them to zero, or whatever initial value I want at the start of the script, or the routine where they're used. For input variables, I set them to nothing before being input, so that I can check for an empty variable and take the appropriate action, such as aborting whatever action would have otherwise been performed.

Having the values stick around after the script finishes can also help in debugging it. Yes, I add echo statements and pauses to check the status of variables, but sometimes I'll just check them from the command line.

Personally, I consider it good practice to make sure that a script always clears or initializes Any important variables before they're used. Having said that, I don't always remember to do that.

To be honest, my script writing process for anything but the simplest of scripts is usually to visualize it in my head, slap some code into an editor, save it, test it, see that it doesn't work, spend time trying to figure out why, make changes, test it again, encounter a new problem, spend more time looking at it, utter some swear words, make more changes, test it again, bang my head on the desk a few times, make more changes, say "f*** it!", come here, start to post a message asking for help, get an idea, test it, it works, cancel post.

Most recently, I couldn't figure out why an if comparison was causing the script to abort, even though it shouldn't even have been executing. Turns out that since I had it as part of another if comparison, it got evaluated anyway, even if the first comparison failed. I still have a hard time remembering that even conditional parts of a script get evaluated 100% of the time.
Post Reply