2010-02-15 11 views
0

Avec les fonctions Powershell personnalisées, toutes les sorties de fonction sont renvoyées. J'essaye de supprimer cette limitation/confusion en écrivant une fonction de wrapper qui retournera juste $ true ou $ false.Powershell - Appel de fonction dynamique

Cependant, je suis aux prises avec l'appel de fonction dynamique. . . en passant spécifiquement les arguments.

Notez que le nom de la fonction et les arguments de la fonction sont passés à "ExecBoolean".

Exemple de code:

# Simplifies calls to boolean functions in Powershells scripts 
# Helps solve this problem -> http://www.vistax64.com/powershell/107328-how-does-return-work-powershell-functions.html 

function Foo([string]$sTest, [int] $iTest) 
{ 
    Write-Host "sTest [" $sTest "]." 
    Write-Host "iTest [" $iTest "]." 
    if ($iTest -eq 1) 
    { 
     return $true 
    } 
    else 
    { 
     return $false 
    } 
} 

function ExecBoolean ([string] $sFunctionName, [array] $oArgs) 
{ 
    Write-Host "Array Length = " $oArgs.Length ", Items = [" $oArgs[0..($oArgs.Length - 1)] "]" 

    $oResult = & $sFunctionName $oArgs[0..($oArgs.Length - 1)] 

    # Powershell returns all function output in oResult, just get the last item in the array, if necessary.      
    if ($oResult.Length -gt 0) 
    { 
     return $oResult[$oResult.Length - 1] 
    } 
    else 
    { 
     return $oResult 
    } 
} 

$oResult = ExecBoolean "Foo" "String1", 1 

Write-Host "Result = " $oResult 

Courant de sortie:

Array Length = 2 , Items = [ String1 1 ] 
sTest [ String1 1 ]. 
iTest [ 0 ]. 
Result = False 

sortie souhaitée:

Array Length = 2 , Items = [ String1 1 ] 
sTest [ String1 ]. 
iTest [ 1 ]. 
Result = True 

Est-ce possible dans Powershell v1.0?

Merci.

Répondre

0
$oResult = & $sFunctionName $oArgs[0..($oArgs.Length - 1)] 

Ici vous passez la fonction qu'un seul argument -ân array- si le second paramètre dans Foo par défaut 0.

Si vous souhaitez simplement ignorer la sortie d'une instruction/expression, il existe des moyens de le faire, par exemple, en le redirigeant vers Out-Null ou en "transtypant" vers void.

+0

Merci, oui, je comprends ce qui se passe. Je pensais/espérais que $ oArgs [0 .. ($ oArgs.Length - 1)] ne serait pas considéré comme un tableau, mais une liste d'arguments 0, 1, 2, etc Je connais le "out-null" "Astuce, mais j'essaie d'éviter les problèmes qui s'ensuivent lorsque les développeurs oublient de l'utiliser ou ne savent tout simplement pas quelles instructions retournent la sortie. – MattH

2

J'utiliser Invoke-Expression comme ceci:

function ExecBoolean ([string] $sFunctionName) 
{ 
    Write-Host "Array Length = " $args.Length ", Items = [" $args[0..($args.Length - 1)] "]" 
    $oResult = Invoke-Expression "$sFunctionName $($args -join ' ')" 
    # Powershell returns all function output in oResult, just get the last item in the array, if necessary.      
    if ($oResult.Length -gt 0) 
    { 
     return $oResult[$oResult.Length - 1] 
    } 
    else 
    { 
     return $oResult 
    } 
} 
ExecBoolean Foo String1 1 

Notez que:

  1. J'utilise $args qui est AMHA plus à l'aise, parce que vous ne faites pas passer les arguments comme un tableau. Cependant, vous pouvez utiliser votre $oArgs sans aucun problème (la seule ligne qui compte est celle avec Invoke-Expression).
  2. Cela ne fonctionnera que pour les types simples (chaînes, entiers, ...), mais pas pour, par exemple, les types simples (chaînes, entiers, ...). FileInfo, car les objets sont convertis en chaînes dans $($args -join ' '). Il existe une option de plus, mais elle est trop verbeuse: ExecBoolean Foo @{sTest="String1"; iTest=1}. Donc, vous passeriez des paramètres dans une table de hachage. Vous auriez besoin de modifier Foo pour accepter la hashtable bien sûr. Dans ce cas, vous pouvez transmettre n'importe quel type, car vous pouvez appeler Foo en utilisant l'opérateur &.
  3. Voir ci-dessous

Je ne recommanderais pas cette approche, en raison des limites (mais il peut arriver que peut-être d'autres viendront avec une meilleure solution).
Si vous voulez juste vous assurer qu'aucune sortie n'est retournée par Foo, vous pouvez créer un script qui analyse d'autres scripts qui appellent Foo et vérifie que chaque appel à "Foo" doit être précédé de $null =.

Si vous passez à PowerShell V2, il est préférable d'appeler l'option Splatting.Pour plus d'informations regarder How and Why to Use Splatting (passing [switch] parameters)

0

Personnellement, je voudrais simplement utiliser:

functionName -as [bool] 

Cela forcera les résultats de la fonction dans un booléen.

Il est beaucoup plus lisible plus tard.

Espérons que cela aide

+0

Selon votre expérience, corrige-t-il de manière fiable les résultats booléens même lorsque la fonction a d'autres résultats? – MattH