Lazy PowerShell Coalesce-Args

A while back I posted a coalesce function for PowerShell that would try to return the first non-null argument passed to it. One drawback of this function is that each argument expression will be evaluated before being passed into the function. This didn’t work so well for posh-git, where each call to git adds undesirable delay to the prompt. To address this issue, I wrote a new ScriptBlock-aware version that allows us to defer execution of the fallback cases until we need them:

function Coalesce-Args {
    $result = $null
    foreach($arg in $args) {
        if ($arg -is [ScriptBlock]) {
            $result = & $arg
        } else {
            $result = $arg
        }
        if ($result) { break }
    }
    $result
}
Set-Alias ?? Coalesce-Args -Force

It’s worth pointing out that this is probably the first time I’ve actually used a foreach statement in PowerShell, specifically for break support. The vast majority of the time it’s preferred to use the pipeline and ForEach-Object.

For an example of usage, here’s how posh-git tries to determine the current branch name in Get-GitBranch:

$b = ?? { git symbolic-ref HEAD 2>$null } `
        { "($(
            Coalesce-Args `
                { git describe --exact-match HEAD 2>$null } `
                {
                    $ref = Get-Content $gitDirHEAD 2>$null
                    if ($ref -and $ref.Length -ge 7) {
                        return $ref.Substring(0,7)+'...'
                    } else {
                        return $null
                    }
                } `
                'unknown'
        ))" }

Related Articles:

About Keith Dahlby

I'm a .NET developer, Git enthusiast and language geek from Cedar Rapids, IA. I work as a software guru at J&P Cycles and studied Human-Computer Interaction at Iowa State University.
This entry was posted in posh-git, powershell. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.leporelo.eu stej

    There is a simillar function in PSCX called Invoke-NullCoalescing (http://pscx.codeplex.com) and many more :)