我假设script
在 PowerShell 模块中的函数上使用范围修饰符会阻止函数被导出。样本:
function script:Get-One { 1 }
当我导入模块时,Get-One
函数被导出。
问题
- 使用
script
范围修饰符将模块功能设为私有是否应该有效? - 如果不是:为什么?我可以使用任何其他范围修饰符吗?
我知道我可以Export-ModuleMember
用来控制要导出的函数,但我只有几个不应该导出的函数。我宁愿指定要忽略的功能。
我假设script
在 PowerShell 模块中的函数上使用范围修饰符会阻止函数被导出。样本:
function script:Get-One { 1 }
当我导入模块时,Get-One
函数被导出。
问题
script
范围修饰符将模块功能设为私有是否应该有效?我知道我可以Export-ModuleMember
用来控制要导出的函数,但我只有几个不应该导出的函数。我宁愿指定要忽略的功能。
script
模块中的范围是多余的,因为默认范围是定义它的脚本/模块。它相当于一个实例变量。global
在模块中类似于静态变量。例如,Posh-Git 使用全局首选项变量来实现 shell 之间的一致性。
我使用了内存模块,但使用 psd1 定义 New-Module 的参数时,想法是一样的
# remove module from namespace for repeated testing
if(Get-Module -Name 'SOTest') { Remove-Module -Name 'SOTest' }
new-Module -Function:'*' -Name:'SOTest' -ScriptBlock {
$global:helpers = [PSCustomObject]@{}
Add-Member -InputObject:$global:helpers -MemberType:ScriptMethod -Name:'HiddenFoo' -Value { return "Private Foo!" }
Add-Member -InputObject:$global:helpers -MemberType:ScriptMethod -Name:'HiddenFooWithArgs' -Value { return "Private " + $args -join ',' + '!' }
Add-Member -InputObject:$global:helpers -MemberType:ScriptMethod -Name:'HiddenFooWithParams' -Value { param ([string]$str, [int]$num); return "Private Str = $str + num; $num!" }
## script: scope refers to module scope, which makes it redundant
function WriteFoo {
Write-Output "PublicFoo!"
}
function WritePrivate {
#This fails, because the private now refers to the function scoped $private:helpers
$private:helpers.HiddenFoo | Write-Verbose -Verbose
}
function WritePrivateShort {
# This works because the helpers object is static across instances
$helpers.HiddenFoo() | Write-Verbose -Verbose
$helpers.HiddenFooWithArgs("Cow", "Moo") | Write-Verbose -Verbose
$helpers.HiddenFooWithParams("Four", 4) | Write-Verbose -Verbose
# This errors due to argument type mismatch
$helpers.HiddenFooWithParams("Five", "Five") | Write-Verbose -Verbose
}
} | Import-Module
# Prefer short errors for this demo
$ErrorView = "CategoryView"
Get-Module -Name 'SOTest'
'WF-----------------'
WriteFoo
'WP-----------------'
WritePrivate
'WPS----------------'
WritePrivateShort
'-------------------'
和输出:
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 0.0 SOTest {WriteFoo, WritePrivate, WritePrivateShort}
WF-----------------
PublicFoo!
WP-----------------
InvalidData: (:) [Write-Verbose], ParameterBindingValidationException
WPS----------------
VERBOSE: Private Foo!
VERBOSE: Private Cow Moo
VERBOSE: Private Str = Four + num = 4!
InvalidArgument: (:) [], RuntimeException
-------------------
对于 Powershell 模块,Export-ModuleMember 是执行此操作的首选方式。
作为替代方案,您可以定义不想从使用它的函数内部导出的函数(例如,在 Begin 块中)。
这使得该功能仅由“父”功能可见,使其有效地私有。
此外,您可以尝试使用 Private 范围,而不是 Script 范围。