Debugging 全局变量:数组的行为与其他变量不同

Debugging 全局变量:数组的行为与其他变量不同,debugging,powershell,global-variables,Debugging,Powershell,Global Variables,我有一个PowerShell脚本,它由一个主PS1文件组成,然后加载多个模块。在其中一个模块中,我定义了一个变量$global:locationsXml,然后在没有全局标志的情况下继续添加到该变量中,效果非常好。我可以引用它,而无需任何其他模块的全局标志。 但是,我还定义了一个$global:loadedDefinitions=@()数组并添加到其中。但是我必须在用+=添加到变量时使用全局标志来引用这个变量。我可以在没有全局标志的任何其他模块中引用它,但在创建模块中我需要它。该模块与xml变量工

我有一个PowerShell脚本,它由一个主PS1文件组成,然后加载多个模块。在其中一个模块中,我定义了一个变量$global:locationsXml,然后在没有全局标志的情况下继续添加到该变量中,效果非常好。我可以引用它,而无需任何其他模块的全局标志。 但是,我还定义了一个$global:loadedDefinitions=@()数组并添加到其中。但是我必须在用+=添加到变量时使用全局标志来引用这个变量。我可以在没有全局标志的任何其他模块中引用它,但在创建模块中我需要它。该模块与xml变量工作方式不同/正确的模块相同。 我还有一个哈希表,我定义它时没有全局标志,但是在加载所有模块的顶级脚本中,我可以在任何地方引用它,而无需全局标志。此外,我还尝试在父脚本中初始化问题数组,如哈希表,但该数组仍然需要填充它的模块中的全局标志。但不是在一个只读取它的不同模块中。 所有这些目前都在Windows7和PS2.0中进行测试。 所以,在我拆开东西之前,我想知道;是否存在已知的bug,其中全局数组的行为与其他全局变量不同,特别是在模块中写入时? 我想在我需要的几个数组中包含用于写入的全局标志并不是什么大问题,但我想了解发生了什么,特别是如果它是某种预期行为而不是bug的话

编辑:澄清一下,这是可行的

Script:
 Define Hash Table without global specifier;
 Load Module;
 Call Function in Module;
  Read and write Hash Table without global specifier;
Script:
  Load Module;
  Call Function in Module;
    Initialize Array with global specifier;
    Append to Array with global specifier;
  Reference Array from anywhere else WITHOUT global specifier;
这是有效的

Script:
 Define Hash Table without global specifier;
 Load Module;
 Call Function in Module;
  Read and write Hash Table without global specifier;
Script:
  Load Module;
  Call Function in Module;
    Initialize Array with global specifier;
    Append to Array with global specifier;
  Reference Array from anywhere else WITHOUT global specifier;
这并不重要

Script:
  Load Module;
  Call Function in Module;
    Initialize Array WITH global specifier;
    Append to Array without global specifier;
  Reference Array from anywhere fails;

这种只使用全局说明符初始化变量,然后不使用全局说明符进行引用的方法适用于其他变量,但不适用于数组,“似乎”是我看到的行为/错误。更奇怪的是,全局说明符只需要在初始化数组的模块中使用,而不需要在任何其他模块中使用。我还需要验证它是否也在初始化它的函数中,和/或只是写入数组,而不是读取。

当您在没有范围说明符的情况下读取变量时,PowerShell首先在当前范围中查找变量,然后,如果找不到,则转到父范围,直到找到变量或到达全局范围。在不使用作用域说明符写入变量时,PowerShell仅在当前作用域中写入该变量

设置StrictMode-Version Latest#以产生VariableIsUndefined错误。
&{
$global:a=1
$global:a#1
$local:a#错误变量未定义。
$a#1将全局$a称为当前范围内的无$a。
$a=2#在当前范围内创建变量$a。
$global:a#1全局变量具有旧值。
$local:a#2新局部变量具有新值。
$a#2指当地$a。
}
仅从变量读取调用对象的方法、属性和索引器的访问器(包括集合访问器)。写入对象不同于写入变量

设置StrictMode-Version Latest#以产生VariableIsUndefined错误。
&{
$global:a=1..3
$global:a-join','#1,2,3
$local:a-join','#错误变量未定义。
$a-join',#1,2,3指全局$a,在当前范围内没有$a。
$a[0]=4;#写入对象(数组),但不写入变量,此处仅读取变量。
$global:a-join','#4,2,3全局变量现在有不同的内容。
$local:a-加入“,”#但您仍然没有本地的。
$a-join',#4,2,3指全局$a,在当前范围内没有$a。
$a+=5#在PowerShell V2中,这相当于$a=$a+5。
#这里有两个对$a的引用。
#第一个是本地$a,因为它是写入变量。
#第二,请参考全局$a,因为当前范围内没有$a。
#$a+5表达式创建新对象,并将其分配给局部变量。
$global:a-join','#4,2,3全局变量具有旧值。
$local:a-join','#4,2,3,5但现在有了具有新值的局部变量。
$a-连接“,”#4,2,3,5指本地$a。
}

因此,如果要从非全局范围写入全局变量,则必须使用
global
范围说明符。但是如果您只想从全局变量中读取,而全局变量并没有被同名的局部变量隐藏,那么您可以省略
global
范围说明符。

Hmm,我认为我的场景有点不同。我没有传递任何讨论过的变量,也没有任何同名的局部变量。我将编辑原始帖子以澄清,因为我可以在那里使用返回。这也是我最初的想法,但我发现,一旦变量是全局变量,那么它在所有范围内都可用,因此不再需要全局说明符。在我的例子中,我运行的一切都是从快捷方式启动的脚本,所以ISE根本不涉及。事实上,我不需要使用全局,我应该能够使用脚本级别的作用域,但我的理解是(有缺陷的?)模块的实现方式需要全局作用域。如果您不使用模块,那么就不需要全局范围。我还需要查看更高版本。可能这种不使用说明符引用全局范围的能力本身就是一个bug,V3或更高版本修复了它。经过测试,它可以在Win8.1/v4中工作。这意味着在没有全局说明符的情况下读取全局变量是有效的。我可能会测试写入行为,但由于我80%的客户仍在Windows 7上,而且不会很快进行更改或升级PowerShell,因此,如果更改或升级PowerShell也无所谓,我必须解决这个问题。该死,为什么我无法格式化评论?或者,更可能的是,我遗漏了什么可以让我格式化评论?;-)无论如何嗯,我有什么巫术