2

我假设script在 PowerShell 模块中的函数上使用范围修饰符会阻止函数被导出。样本:

function script:Get-One { 1 }

当我导入模块时,Get-One函数被导出。

问题

  1. 使用script范围修饰符将模块功能设为私有是否应该有效?
  2. 如果不是:为什么?我可以使用任何其他范围修饰符吗?

我知道我可以Export-ModuleMember用来控制要导出的函数,但我只有几个不应该导出的函数。我宁愿指定要忽略的功能。

4

2 回答 2

1

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
-------------------
于 2015-01-07T21:57:28.770 回答
0

对于 Powershell 模块,Export-ModuleMember 是执行此操作的首选方式。

作为替代方案,您可以定义不想从使用它的函数内部导出的函数(例如,在 Begin 块中)。

这使得该功能仅由“父”功能可见,使其有效地私有。

此外,您可以尝试使用 Private 范围,而不是 Script 范围。

于 2015-01-07T09:13:12.570 回答