Tenho uma função cujo name
parâmetro desejo fornecer conclusão de tabulação, os valores de conclusão de tabulação são nomes de arquivos encontrados em c:\temp
. Além de usar os arquivos em c:\temp
como valores, também desejo adicionar valores de conclusão de tabulação adicionais. Abaixo está a função
Function foo{
Param(
[ValidateSet([layoutNames], ErrorMessage = """{0}"" Is not a valid Layout name")]
$Name
)
$name
}
e a layoutNames
classe, que é usada pelo name
parâmetro:
Class layoutNames : System.Management.Automation.IValidateSetValuesGenerator{
[string[]] GetValidValues(){
#return @((Get-ChildItem -path 'c:\temp' -File).BaseName, "valueFoo", "valueBar") #tab completetion only suggests "valueFoo" and "valueBar"
#return @("valueFoo", "valueBar", (Get-ChildItem -path 'c:\temp' -File).BaseName) #tab completetion only suggests "valueFoo" and "valueBar"
return @( #tab completetion suggests "valueFoo" and "valueBar" and the file names.
"valueFoo", "valueBar"
(Get-ChildItem -path 'c:\temp' -File).BaseName
)
}}
Com o acima, apenas o terceiro return
exemplo funciona, a única diferença é uma nova linha... eu acho.
Passei um bom tempo tentando descobrir isso. Inicialmente, comecei com uma instrução return que se parecia com esta:
return [string[]]("valueFoo", "valueBar", (Get-ChildItem -path 'c:\temp' -File).BaseName)
mas continuei mudando, pois nada estava funcionando, até que finalmente consegui usar o operador de matriz @()
.
O ponto crucial do meu problema é por que a classe, quando declarada da seguinte maneira, não funciona como pretendido com a foo
função, ou seja, sugere ambos valueFoo
, valueBar
e os nomes dos arquivos emc:\temp
Class layoutNames : System.Management.Automation.IValidateSetValuesGenerator{
[string[]] GetValidValues(){
#return [string[]]("valueFoo", "valueBar",(Get-ChildItem -path 'C:\Users\INDESK\AppData\Roaming\GPSoftware\Directory Opus\Layouts' -File).BaseName) # no files names are suggested. only 'valueFoo' and 'valueBar' are suggested
#return [string[]]("valueFoo", "valueBar",((Get-ChildItem -path 'C:\Users\INDESK\AppData\Roaming\GPSoftware\Directory Opus\Layouts' -File).BaseName)) # no files names are suggested. only 'valueFoo' and 'valueBar' are suggested
return [string[]](((Get-ChildItem -path 'C:\Users\INDESK\AppData\Roaming\GPSoftware\Directory Opus\Layouts' -File).BaseName),"valueFoo", "valueBar") # no files names are suggested. only 'valueFoo' and 'valueBar' are suggested
}}
Estou no pwsh 7.4/win11
O motivo pelo qual o terceiro exemplo funciona é porque não há vírgula antes da
Get-ChildItem
expressão. Veja os detalhes do operador vírgula,
:É como fazer:
Se você colocar todas as expressões em uma única linha, estará essencialmente correndo o risco de criar uma matriz irregular ao
Get-ChildItem
gerar 2 ou mais itens:E se não retornar nenhum item, você terminará com um
null
elemento:Se você estiver usando o operador de subexpressão Array
@( )
e quiser colocar todos os elementos em uma única linha, o melhor que você pode fazer é usar;
como separador de itens (que simboliza uma nova linha/nova instrução):Para complementar a resposta útil de Santiagio :
Outra opção que evita a criação inadvertida de matrizes irregulares é usar a concatenação de matrizes por meio do
+
operador :+
operação for do tipo array (um array ou um tipo de dado similar que o PowerShell enumeraria automaticamente no pipeline), o RHS é "anexado" ao array:+
para "adicionar" dois arrays planos resulta em outro array plano.Portanto, você pode fazer o seguinte:
Observe que, talvez surpreendentemente,
,
(o operador construtor de matriz ) tem precedência maior que , então a matriz LHS ( ) não requer fechamento em , o operador de agrupamento .+
'valueFoo', 'valueBar'
(...)