Gor*_*don 5 powershell global-variables
我有一些脚本和模块,它们使用全局变量来处理许多事情.我的日志记录可以采用三种形式之一; Terse,Verbose和Validation(详细记录没有实际操作,只是验证提供的数据).我还有许多函数,这些函数根据它们运行的上下文(用户或机器)做出不同的响应,并且正在执行的Action(Rollout,Remove,Conform,Relocate)也会影响事物.所以,到目前为止,我已经使用了三个全局变量并且它已经有效,但我知道最佳实践是避免全局变量.也就是说,解决它的唯一方法似乎是在一个模块中使用一些Get和Set函数,以及Script级别变量.这似乎增加了复杂性而没有真正解决太多,因为我仍然有比使用它们的函数更高的变量.或者,我可以将这三个值传递给需要它们的每个函数,但也有很多参数几乎没有增加价值.所以我开始想知道,这是一个全局变量确实是正确答案的地方吗?它们的存在表明必须存在一些应该使用它们的情况,并且这种情况开始变得恰到好处.
在特定场景中使用全局变量没有任何问题,特别是对于全局设置或单个对象,这些对象只定义一次,然后在其余代码中使用而无需进一步修改.关键是避免改变变量.
你应该不使用全局变量是运输状态,即改变的值.如果在代码中的不同位置更改全局变量的值,则故障排除问题会成为后方的巨大痛苦,因为您将信息传递到常规"通道"(参数,返回值)之外.如果您需要在代码中的其他位置修改全局变量,那么几乎总是表明您应该重新评估您的体系结构.
PowerShell 实现了动态范围。这在当今的语言设计中是一个罕见的选择,但正确应用动态范围可以让开发人员比全局变量更好地控制名称冲突。要了解这如何适用于您的案例,让我们考虑以下玩具模块:
# File Module1.psm1
$module = "Module1"
$Context = "User"
function Log-Message( $message ) {
Write-Host "$module/${action}: $message ($LogLevel-$Context)"
}
function CommonCode {
Log-Message "In CommonCode"
}
function Invoke-Rollout( $LogLevel = "Terse", $Context=$script:Context) {
$action = "Rollout"
CommonCode
}
function Invoke-Remove( $LogLevel = "Terse", $Context=$script:Context) {
$action = "Remove"
CommonCode
}
function Set-Module1( $Context=$script:Context ) {
$script:Context = $Context
}
Export-ModuleMember -Function Invoke-Rollout, Invoke-Remove, Set-Module1
Run Code Online (Sandbox Code Playgroud)
这里的关键是,在Log-Message中,变量$module,$action,$LogLevel和$LogContext是不是 全局变量,相反,他们是自由变量谁的范围尚未确定。在运行时,PowerShell 将根据调用堆栈中的最新定义动态确定它们的绑定...
与其尝试详细解释这一点,您最好还是玩玩这个玩具模块,看看动态范围对日志记录有什么影响。以下是我尝试过的一些实验:
PS C:\temp> Import-Module -Force .\Module1.psm1
PS C:\temp> Invoke-Rollout
Module1/Rollout: In CommonCode (Terse-User)
PS C:\temp> # For Sticky Change -- Set-Module1
PS C:\temp> Set-Module1 -Context Machine
PS C:\temp> Invoke-Rollout
Module1/Rollout: In CommonCode (Terse-Machine)
PS C:\temp> Invoke-Remove -LogLevel Verbose -Context XXX
Module1/Remove: In CommonCode (Verbose-XXX)
PS C:\temp> Invoke-Remove -Context User
Module1/Remove: In CommonCode (Terse-User)
PS C:\temp> $Context = "FooBar" # This should have no effet on Module1
PS C:\temp> Invoke-Remove
Module1/Remove: In CommonCode (Terse-Machine)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
931 次 |
| 最近记录: |