2

This one has me thoroughly confused. In some scenarios, running a script that dot-sources another script that defines a class does not reflect changes to the class. Here's the repro.

Script common.ps1:

class A
{
    A()
    {
        Write-Host 'hi'
    }
}

Script myscript.ps1:

. .\common.ps1
[A]::new() | out-null

In a powershell terminal, I then run

. .\common.ps1
[A]::new() | out-null
.\myscript.ps1

outputs

hi
hi

I then change common.ps1 by replacing 'hi' with 'bye', and again run

. .\common.ps1
[A]::new() | out-null
.\myscript.ps1

To get this output (my comments added):

bye # expected
hi # what?!?!

The fact that the change is not-reflected when myscript.ps1 does the dot sourcing but is when the dot sourcing is done locally blows my mind. If I don't dot-source locally, running myscript.ps1 always reflects any changes to common.ps1. And it is only when my change is to some part of the class that it does not have an effect (I can add a Write-Host outside of the class and it will show up).

What's going on? Somehow myscript.ps1 can't load the updated class even though the local shell can? I imagine this is related to this question but the inconsistency between local shell and myscript.ps1 has me scratching my head.

aggieNick02
  • 2,557
  • 2
  • 23
  • 36
  • https://stackoverflow.com/questions/1337961/powershell-unload-module-completely and https://stackoverflow.com/questions/21394358/powershell-how-does-the-powershell-instantiate-c-sharp-classes – Kory Gill Oct 12 '17 at 22:27
  • Just saw other wonkiness that didn't involve a class, where the dot-sourcing seemed to be one-behind the changes. So perhaps this isn't even class specific, but classes are just a way to expose it. – aggieNick02 Oct 12 '17 at 22:57
  • PowerShell try to resolve type tokens at parse time. If it succeed, then it record result in parsed syntax tree, rather then resolve type token in runtime each time. Also PowerShell cache parsed script files. If it see that file does not changed from last time, then it reuse already parsed syntax tree, rather than reparse file again and re-resolving type tokens in new context. – user4003407 Oct 13 '17 at 01:53
  • @PetSerAI - That doesn't explain why the changes to the class have an effect in the top-level shell but not in the called script, does it? Both places dot source the file after the change, but only one gets the changes. – aggieNick02 Oct 13 '17 at 14:53
  • *Also PowerShell cache parsed script files.* Add/remove some meaningless space in script and try again. – user4003407 Oct 13 '17 at 17:42
  • This has no effect. – aggieNick02 Oct 13 '17 at 20:34
  • 1
    @aggieNick02 It [work](https://i.stack.imgur.com/hUmN5.png) for me. – user4003407 Oct 13 '17 at 20:56
  • @PetSerAl - Wow, you are right, my apologies. I had added and deleted a space, then saved, which updated the modtime on the file but did not fix the issue. But if I actually change the file (only add or remove a space, not both) so that the file is different, the issue goes away. This means the caching is done not off the modtime of the file, but off of some hash of it. – aggieNick02 Oct 13 '17 at 22:51
  • @PetSerAl If you want to post the comment about the caching as an answer, I'm happy to accept it. Thanks for going to such trouble to try my code out and figure out the issue. – aggieNick02 Oct 13 '17 at 22:53

0 Answers0