PowerShell: Add-Member, другие поточные фукнции, $_ и замыкания
Зачастую при добавлении ряда статических свойств объекту класса PSObject при вычислении следующих свойств уже хочется использовать значения добавленных ранее. И при этом не хочется, чтобы код выглядел громоздко. В этой заметке как раз и предлагаю решение этой задачи.
Сразу приведу код, который будет работать неправильно:
function Add-Attribute { get-content ` -path $csvFile ` | convertFrom-csv ` -useCulture ` | Add-Member -PassThru -MemberType noteProperty -Name cn -Value ( ( $_.sn, $_.givenName, $_.middleName | ? { $_ } ) -join ' ' ) ` | Add-Member -PassThru -MemberType noteProperty -Name name -Value ( $_.cn ) ` | Add-Member -PassThru -MemberType noteProperty -Name displayName -Value ( $_.cn ) ` ;
Причина ошибки в том, что при вызове поточных функций переменная $_
не принимает передаваемого на “вход” поточной функции объекта, и её нельзя использовать при вычислении параметров поточной функции. А как хочется…
А теперь приведу код, который уже будет работать правильно:
function Add-Attribute { param ( [Parameter( Mandatory=$true, Position=0, ValueFromPipeline=$false, ValueFromPipelineByPropertyName=$false )] [string] $Name , [Parameter( Mandatory=$false, Position=1, ValueFromPipeline=$false, ValueFromPipelineByPropertyName=$false )] [scriptBlock] $Value = {$null} , [Parameter( Mandatory=$true, Position=2, ValueFromPipeline=$true )] [PSObject] $InputObject ) Add-Member ` -PassThru ` -InputObject $InputObject ` -MemberType noteProperty ` -ErrorAction SilentlyContinue ` -Name $Name ` -Value ( $InputObject | % { & $Value } ) ` ; } get-content ` -path $csvFile ` | convertFrom-csv ` -useCulture ` | ? { $_.sn } ` | % { $_ ` | Add-Attribute extensionName ` | Add-Attribute personalTitle ` | Add-Attribute generationQualifier ` | Add-Attribute cn { ( $_.sn, $_.givenName, $_.middleName | ? { $_ } ) -join ' ' } ` | Add-Attribute name { $_.cn } ` | Add-Attribute displayName { $_.cn } ` | Add-Attribute initials { ( $_.givenName, $_.middleName | ? { $_ } | % { $_[0] + '.' } ) -join ' ' } ` ; } ` ;
Как видно в приведённом выше коде, для того, чтобы в конвейере в выражениях, предназначенных для вычисления значения параметров поточной функции, использовать в качестве $_ объект, поданный “на вход” поточной функции, можно использовать вместо непосредственного вычисления выражения передачу в качестве аргумента функционал, который в функции мы вычисляем в нужный момент следующим вызовом:
$InputObject | % { & $Value }
Вся прелесть PowerShell в данном случае в том, что при передаче функционала PowerShell не создаст замыкания, и значение $_
будет вычисляться в момент выполнения кода с учётом областей видимости переменных в точке исполнения кода.
RSS комментарии
Обратная ссылка