Let's take the classic first-order functions example:
function Get-MyName { "George" }
function Say-Hi([scriptblock]$to) {
Write-Host ("Hi "+(& $to))
}
This works just fine:
Say-Hi { "Fred Flintstone" }
this does not:
Say-Hi Get-MyName
because Get-MyName is evaluated, not passed as a value itself. How do I pass Get-MyName as a value?
You have to pass Get-Myname as a scriptblock, because that's how you've defined the variable type.
Say-Hi ${function:Get-MyName}
If you are ready to sacrifice the [scriptblock]
parameter type declaration
then there is one more way, arguably the simplest to use and effective. Just
remove [scriptblock]
from the parameter (or replace it with [object]
):
function Get-MyName { "George" }
function Say-Hi($to) {
Write-Host ("Hi "+(& $to))
}
Say-Hi Get-MyName
Say-Hi { "George" }
So now $to
can be a script block or a command name (not just a function but also alias, cmdlet, and script).
The only disadvantage is that the declaration of Say-Hi
is not so self describing.
And, of course, if you do not own the code and cannot change it then this is
not applicable at all.
I wish PowerShell has a special type for this, see this suggestion.
In that case function Say-Hi([command]$to)
would be ideal.
This might be a better example to illustrate the question, and details of execution scope. @mjolinor's answer appears to work nicely for this use case:
function Get-MyName($name) { $name; throw "Meh" }
function Say-Hi([scriptblock]$to) {
try {
Write-Host ("Hi "+(& $to $args)) # pass all other args to scriptblock
} catch {
Write-Host "Well hello, $_ exception!"
}
}
The command and its output:
PS C:\> Say-Hi ${function:Get-MyName} 'George'
Well hello, Meh exception
In particular, I'm using this pattern for wrapping functions that work with a flaky remote SQL Server database connection, which sleep, then retry several times before finally succeeding or throwing a higher exception.
Strictly based on your code, the correct answer is this:
Say-Hi {(Get-MyName)}
This will produce "Hi George"
来源:https://stackoverflow.com/questions/15977178/how-to-pass-a-named-function-as-a-parameter-scriptblock