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

时间:2015-02-15 14:19:38

标签: debugging powershell global-variables

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

编辑:为了澄清,这是有效的

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;

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

1 个答案:

答案 0 :(得分:1)

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

Set-StrictMode -Version Latest #To produce VariableIsUndefined error.
&{
    $global:a=1
    $global:a   #1
    $local:a    #  Error VariableIsUndefined.
    $a          #1 Refer to global, $a as no $a in current scope.
    $a=2        #  Create variable $a in current scope.
    $global:a   #1 Global variable have old value.
    $local:a    #2 New local variable have new value.
    $a          #2 Refer to local $a.
}

调用对象的方法,属性和索引器的访问器(包括set访问器)只能从变量中读取。写入对象与写入变量不同。

Set-StrictMode -Version Latest #To produce VariableIsUndefined error.
&{
    $global:a=1..3
    $global:a-join',' #1,2,3
    $local:a -join',' #        Error VariableIsUndefined.
    $a       -join',' #1,2,3   Refer to global $a, as no $a in current scope.
    $a[0]=4;          #        Write to object (Array) but not to variable, variable only read here.
    $global:a-join',' #4,2,3   Global variable have different content now.
    $local:a -join',' #        And you still does not have local one.
    $a       -join',' #4,2,3   Refer to global $a, as no $a in current scope.
    $a+=5             #        In PowerShell V2 this is equivalents to $a=$a+5.
                      #        There are two reference to $a here.
                      #        First one refer to local $a, as it is write to variable.
                      #        Second refer to global $a, as no $a in current scope.
                      #        $a+5 expression create new object and you assing it to local variable.
    $global:a-join',' #4,2,3   Global variable have old value.
    $local:a -join',' #4,2,3,5 But now you have local variable with new value.
    $a       -join',' #4,2,3,5 Refer to local $a.
}

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