2014-07-03 16 views
8

Gibt es eine Möglichkeit, die Rückgabewerte innerhalb einer Funktion zu löschen, damit ich sicherstellen kann, dass der Rückgabewert meinen Erwartungen entspricht? Oder vielleicht deaktivieren Sie dieses Verhalten für die Funktion?Gesonderten Ausgangs-/Rückgabewert in einer Powershell-Funktion löschen

In diesem Beispiel erwarte ich, dass der Rückgabewert ein Arraylist enthält („Hallo“, „Welt“)

function GetArray() 
{ 
    # $AutoOutputCapture = "Off" ? 
    $myArray = New-Object System.Collections.ArrayList 
    $myArray.Add("Hello") 
    $myArray.Add("World") 

    # Clear return value before returning exactly what I want? 
    return $myArray 
} 

$x = GetArray 
$x 

jedoch sein, enthält die Ausgabe den erfassten Wert aus den Add-Operationen.

0 
1 
Hello 
World 

Ich finde dieses „Feature“ von Powershell sehr ärgerlich, weil sie es wirklich einfach zu brechen Ihre Funktion nur durch eine andere Funktion aufrufen macht, die Sie wissen, hat keinen Wert zurückgegeben.

aktualisieren

Ich verstehe, gibt es Möglichkeiten, die Ausgabe zu verhindern, gefangen zu werden (wie in einer der Antworten unten beschrieben), aber das erfordert, dass Sie wissen, dass eine Funktion einen Wert tatsächlich zurückgibt. Wenn Sie eine andere Powershell-Funktion aufrufen, kann es sein, dass jemand in Zukunft diese Funktion ändert, um einen Wert zurückzugeben, der dann Ihren Code unterbricht.

+1

Wie haben Sie dieses Problem gelöst? Dies ist eine sehr ärgerliche Eigenschaft der Powershell, die nicht die Kontrolle über den Rückgabewert erlaubt. – Feru

+0

Ich habe einfach überall [void] benutzt. Ich entschied auch, dass es einfacher war, komplexe Dinge in C# zu machen, dann benutze Powershell, um sie zusammen zu kleben. – Mas

Antwort

6

Rohrausgang Out-Null, umlenken Ausgabe an $null, oder Präfix die Funktionsaufrufe mit [void]:

$myArray.Add("Hello") | Out-Null 

oder

$myArray.Add("Hello") >$null 

oder

[void]$myArray.Add("Hello") 
+0

Ja, ich weiß das, aber das bedeutet, dass ich die Ausgabe jedes Funktionsaufrufs auf Null pipesieren muss, um zu garantieren, dass meine Ausgabe nicht beschädigt ist, was ein großer Schmerz ist. Und wenn ich es vergesse und der Code funktioniert, kann es in der Zukunft sein, dass jemand anders eine Powershell-Funktion ändert und eine andere Funktion bricht. – Mas

+1

Es scheint die Antwort ist, dass es keine Lösung für dieses Problem gibt, außer jedem Funktionsaufruf, der sehr ärgerlich ist. – Mas

0

Warum nicht das Powershell Array Objekt anstelle der .Net ArrayList verwenden?

Man könnte so etwas wie tun:

function GetArray() { 
    # set $myArray as a powershell array 
    $myArray = @() 
    $myArray+="Hello" 
    $myArray+="World" 
    # [email protected]("Hello", "World") would work as well 

    return $myArray 
} 

Dieses eine "saubere" Array wird wieder, wie erwartet.

Wenn Sie wirklich eine System.Collections.ArrayList bekommen müssen, können Sie es in zwei Schritten tun:

  • einen Powershell-Array erstellen, wie oben
  • Ihren Powershell-Array konvertieren erklärte in einer .Net Arraylist auf diese Weise:

    # Get the powershellArray 
    $x = getArray 
    # Create a .Net ArrayList 
    $myArrayList = New-Object System.Collections.ArrayList 
    # Fill your arraylist with the powershell array 
    $myArrayList.AddRange($x) 
    

der Hoffnung, dies hilft ein wenig.

+2

Der Code in der Frage war nur ein Beispiel für das unerwünschte Verhalten. Ich frage im Allgemeinen, wie ich mit dieser Situation umgehen soll. – Mas

2

Ich habe auch genau diese Frustration! Ich hatte eine Funktion, wo eine Variable zählen soll $ <variablename> ++

Ausgenommen. Ich hatte das "++" am Ende in einer Iteration vergessen. Dadurch wurde der Wert der Variablen an den Ausgabepuffer gesendet. Es war sehr ärgerlich und zeitaufwendig zu finden! MS sollte mindestens die Möglichkeit bieten, den Ausgabepuffer zu leeren, bevor der Benutzer seinen gewünschten Rückgabewert zuweisen kann. Anywhow ... Ich glaube, ich habe eine Arbeit herum.

Da ich am Ende der Funktion einen Rückgabewert zugewiesen habe, ist mein gewünschter Wert immer der letzte Eintrag des Ausgabepufferarrays. Also habe ich die Art und Weise änderte ich meine Funktionen aufrufen:

If (FunctionName (parameters)) {} 

An:

If ((FunctionName (parameters))[-1]) {} 

Mein besonderes Szenario mich gebissen, wenn ich eine Funktion $ False Rückkehr zu erfassen versuchte. Wegen meines obigen Tippfehlers sah meine IF-Anweisung es als wahr an, wegen des Mülls in der Ausgabe, obwohl meine letzte Funktionsausgabe "Return $ False" war. Die letzte Ausgabe, die von der Funktion zugewiesen wurde, war der $ False-Wert aufgrund des Problems, das daraus resultierte, dass der Tippfehler eine falsche Berechnung verursachte. Ändern Also meine Funktion Zurück Bewertung zu:

If (!((FunctionName (parameters))[-1])) {#something went wrong!} 

den Trick tat, indem sie mir nur das letzte Element des Ausgangs-Array zu bewerten. Ich hoffe, das hilft anderen.

+0

Dies ist ein schöner Trick, wenn Sie einen einzelnen Rückgabewert erwarten. Ich werde es mir merken. – Mas

+0

Beachten Sie, dass dies nicht funktioniert, wenn Sie einen einzelnen Rückgabewert haben, bei dem es sich um eine Hashtabelle handelt - Sie würden versuchen, darauf zu indizieren. Lösung: Setzen Sie den Funktionsaufruf mit 'array' wie '[array] (Funktionsname (Parameter))' voran, um zu erzwingen, dass das Ergebnis ein Array von Rückgabewerten ist. Dies würde dann Ihre Hashtabelle am erwarteten Index enthalten. –

2

Ich wollte das nur posten, falls es hilft. Ich hatte mehrere Funktionen, die ich anrief. Jede Funktion gab eine 0 oder eine 1 zurück. Ich habe das verwendet, um zu sehen, ob alles funktioniert hat.

Also im Grunde ...

function Funct1 
{ 
    # Do some things 
    return 1 
} 

$myResult += Funct1 
$myResult += Funct2 
$myResult += Funct3 
if ($myResult -eq 3) { "All is good" } 

Alles ging zusammen gut, bis ich eine Funktion, die hatte einige Copy-Item und solche Befehle hinzugefügt.

Lange Geschichte kurz und eine Stunde oder zwei Ich werde nie zurückkommen, entdeckte ich das gleiche Problem mit dieser verdammten Pipeline-Sache. Wie auch immer, mit der Hilfe von Seiten wie dieser, fand ich den saubersten Weg, um sicherzustellen, dass Sie Ihre "Return" und sonst nichts bekommen.

$myResult += Funct1 -split " " | Select-Object -Last 1 
$myResult += Funct2 -split " " | Select-Object -Last 1 
$myResult += Funct3 -split " " | Select-Object -Last 1 
0

Ich stieß auf das gleiche Problem. In PS würde eine Funktion alle Informationen der Ausgangsleitung zurückgeben. Es wird schwierig, | Out-Null Rest des Codes in der Funktion. Ich arbeitete um dieses Problem, indem ich die Rückgabevariable als Referenzparameter [ref] übergab. Dies funktioniert durchgängig. Überprüfen Sie den folgenden Beispielcode. Hinweis: Ein Teil der Syntax ist wichtig, um Fehler zu vermeiden. z.B. Parameter hat ([ref]$result)

function DoSomethingWithFile([ref]$result, [string]$file) 
{ 
    # Other code writing to output 
    # .... 

    # Initialize result 
    if (Test-Path $file){ 
     $result.value = $true 
    } else { 
     $result.value = $false 
    } 
} 
$result = $null 
DoSomethingWithFile ([ref]$result) "C:\test.txt" 
2

Unter Verwendung der Informationen von user1654962 in Klammern übergeben werden, hier ist die Art und Weise, die ich um dieses Problem Powershell gearbeitet. Da, wenn Ausgabeinformationen vorhanden sind, PowerShell es als ein Array zurückgibt, entschied ich mich dafür zu sorgen, dass die Funktionsausgabe immer ein Array war. Dann kann die aufrufende Zeile [-1] verwenden, um das letzte Element des Arrays zu erhalten, und wir erhalten einen konsistenten Rückgabewert.

function DoSomething() 
{ 
    # Code that could create output 
    Write-Output "Random output that we don't need to return" 
    Write-Output "More random output" 

    # Create the return value. It can be a string, object, etc. 
    $MyReturnString = "ImportantValue" 

    # Other code 

    # Make sure the return value is an array by preceding it with a comma 
    return ,$MyReturnString 
} 

$CleanReturnValue = (DoSomething())[-1]