Compile the following with dotnet build
```c#
using System;
namespace exitcodes
{
class Program
{
static int Main(string[] args)
{
var returnValue = args.Length == 1 ? int.Parse(args[0]) : 0;
Console.WriteLine($"I shall return {returnValue}");
return returnValue;
}
}
}
Write the following script
```powershell
dotnet run 1
Write-Host "LastExitCode=$LastExitCode"
$LastExitCode=0
dotnet run 1
Write-Host "LastExitCode=$LastExitCode"
Run the script:
.\exitcode.ps1
I shall return 1
LastExitCode=1
I shall return 1
LastExitCode=1
I shall return 1
LastExitCode=1
I shall return 1
LastExitCode=0
Name Value
---- -----
PSVersion 6.2.1
PSEdition Core
GitCommitId 6.2.1
OS Microsoft Windows 10.0.18362
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Modify the last line of your script to this:
Write-Host "LastExitCode=$LastExitCode, `$global:LastExitCode=$global:LastExitCode"
When you assigned 0 to $LastExitCode a few lines above this one, you made a local copy of $LastExitCode. You are not changing the value of the globally scoped $LastExitCode. After that, when you access $LastExitCode with no scope modifier, PowerShell looks in the local scope first, then in the next scope up until it reaches the global scope.
You can avoid this issue by always using the global scope modifier e.g. $global:LastExitCode to access this variable.
Thanks! Is there a powershell strictness level that disallows implicit sneaky super scope overriding without an explicit override keyword?
In general, modifying a variable that originates in a different scope will result in it being copied (kinda like F#'s "masking" behaviour with variables) to the local scope if you're not specifying the scope to modify it at, IIRC.
Thanks for the info. Wish there was a way to turn off automatic variable copying, but at least I understand what's going on now :)
Yeah, in PowerShell I've always referred to it as copy on write. In PowerShell's dynamic scoping approach (as opposed to lexical scoping) it's about the only way to maintain your sanity. :-) For example, I write a script that you use. Where you invoke my scirpt, you have a variable named $mypath. Down in my script, I also have a variable called $mypath. If my modifications to that variable affected your version of $mypath - you'd be pulling your hair trying to figure out how/who changed your variable's value. :-)
Yea, dynamic scoping is not my kind of strudel :)
Most helpful comment
Yeah, in PowerShell I've always referred to it as
copy on write. In PowerShell's dynamic scoping approach (as opposed to lexical scoping) it's about the only way to maintain your sanity. :-) For example, I write a script that you use. Where you invoke my scirpt, you have a variable named$mypath. Down in my script, I also have a variable called$mypath. If my modifications to that variable affected your version of$mypath- you'd be pulling your hair trying to figure out how/who changed your variable's value. :-)