ephemeris
ephemeris

Reputation: 785

How to wrap a generic powershell function with set parameters into a new more specified function?

Correct me if I'm misusing terminology but here's what I have, a generic function:

function runNode ([string]$argList=@() , $fwd=".\", [string]$app="", [switch]$Process, [switch]$NoNewWindow)
{
$appName=$app+"Node"
$processNode=start-process node -ArgumentList:$argList  -WorkingDirectory:$fwd -PassThru -NoNewWindow:$NoNewWindow
}

I want something like that (doesn't work, can't find [function] type)

[function]$myRunNode=runNode -argList "$projectFolder/node_modules/grunt/bin/grunt","serve","flag1" -fwd $projectFolder -app "appName" -Process

Can I do something like that? I want just to fix parameters. I can wrap a function call but passing parameters along feels very awkward. Adding default parameters won't do - I need several specified functions like that.

Upvotes: 0

Views: 207

Answers (2)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174555

What you want is to return a scriptblock (an executable block of code) from your function. You may also want to avoid assigning values to variables inside the function if you want to use them later:

function Get-NodeRunner {
    param(
        [string[]]$argList,
        [string]$fwd = $pwd, 
        [string]$app, 
        [switch]$Process
    )

    return {
        param(
            [switch]$NoNewWindow
        )

        $StartProcessParams = @{
            FilePath = 'node'
            ArgumentList = $argList
            WorkingDirectory = $fwd
            PassThru = $Process.IsPresent
            NoNewWindow = $NoNewWindow
        }

        return New-Object psobject -Property @{
            AppName = "${app}Node"
            Process = Start-Process @StartProcessParams
        }
    }.GetNewClosure()
}

The GetNewClosure() method will have the scriptblock close over the variables inside the Get-NodeRunner function, including the parameters passed, and then you can do:

# Generate your function
$NodeRunner = Get-NodeRunner -argList "$projectFolder/node_modules/grunt/bin/grunt","serve","flag1" -fwd $projectFolder -app "appName" -Process

# Run it using the call operator (&)
& $NodeRunner -NoNewWindow:$false

Upvotes: 2

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200313

If you want to wrap a function, just wrap the function:

function myRunNode($ProjectFolder) {
    runNode -argList "$ProjectFolder/node_modules/grunt/bin/grunt","serve","flag1" -fwd $ProjectFolder -app "appName" -Process
}

myRunNode -ProjectFolder 'C:\some\folder'

If you want to define an anonymous function, use a scriptblock:

$myRunNode = {
    runNode -argList "$projectFolder/node_modules/grunt/bin/grunt","serve","flag1" -fwd $projectFolder -app "appName" -Process
}

$projectFolder = 'C:\some\folder'
$myRunNode.Invoke()

Upvotes: 1

Related Questions