Использование модификатора области сценария для функций PowerShell в модулях не имеет эффекта?

Я предположил, что использование модификатора области действия script для функции в модуле PowerShell предотвратит экспорт функции. Образец:

function script:Get-One { 1 }

Когда я импортирую модуль, функция Get-One экспортируется.

Вопросы

  1. Предполагается ли использование модификатора области видимости script для приватности функций модуля?
  2. Если нет: Почему? Любые другие модификаторы области, которые я могу использовать?

Я знаю, что могу использовать Export-ModuleMember для управления экспортируемыми функциями, но у меня есть только несколько функций, которые не следует экспортировать. Я бы предпочел указать, какие функции игнорировать.


person knut    schedule 07.01.2015    source источник
comment
В вашем файле psm1 есть FunctionsToExport = '*'?   -  person Eris    schedule 07.01.2015
comment
Также взгляните на stackoverflow.com/questions/6032344/   -  person Eris    schedule 07.01.2015
comment
Я закомментировал строку FunctionsToExport = '*' в файле манифеста модуля PowerShell (psd1), но это не дало никакого эффекта. Все функции по-прежнему экспортируются. У меня нет такой строки в файле psm1.   -  person knut    schedule 07.01.2015


Ответы (2)


Область script в модуле является избыточной, поскольку областью действия по умолчанию является скрипт/модуль, в котором она определена. Это эквивалент переменной экземпляра. global в модуле сродни статической переменной. Posh-Git, например, использует глобальную переменную настроек для согласованности между оболочками.

Я использовал модуль в памяти, но идея та же самая при использовании 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
-------------------
person Eris    schedule 07.01.2015

Для модуля Powershell предпочтительнее использовать Export-ModuleMember.

В качестве альтернативы вы можете определить функцию, которую вы не хотите экспортировать, из функций, которые ее используют (например, в блоке «Начало»).

Это делает функцию видимой только для "родительской" функции, что делает ее фактически приватной.

Кроме того, вы можете попробовать использовать область Private вместо области Script.

person Mathieu Buisson    schedule 07.01.2015
comment
Функции по-прежнему экспортируются после того, как я изменил модификатор области действия с script на private. Частные функции должны быть доступны для использования несколькими публичными функциями в модуле. - person knut; 07.01.2015
comment
Вы пытались определить функции внутри другой функции, как я объяснил выше? - person Mathieu Buisson; 07.01.2015