Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle $null in the pipeline

Tags:

I often have the following situation in my PowerShell code: I have a function or property that returns a collection of objects, or $null. If you push the results into the pipeline, you also handle an element in the pipeline if $null is the only element.

Example:

$Project.Features | Foreach-Object { Write-Host "Feature name: $($_.Name)" } 

If there are no features ($Project.Features returns $null), you will see a single line with "Feature name:".

I see three ways to solve this:

if ($Project.Features -ne $null) {   $Project.Features | Foreach-Object { Write-Host "Feature name: $($_.Name)" } } 

or

$Project.Features | Where-Object {$_ -ne $null) | Foreach-Object {    Write-Host "Feature name: $($_.Name)"  } 

or

$Project.Features | Foreach-Object {    if ($_ -ne $null) {     Write-Host "Feature name: $($_.Name)" }   } } 

But actually I don't like any of these approaches, but what do you see as the best approach?

like image 933
Serge van den Oever Avatar asked Dec 05 '10 00:12

Serge van den Oever


1 Answers

I don't think anyone likes the fact that both "foreach ($a in $null) {}" and "$null | foreach-object{}" iterate once. Unfortunately there is no other way to do it than the ways you have demonstrated. You could be pithier:

$null | ?{$_} | % { ... } 

the ?{$_} is shorthand for where-object {$_ -ne $null} as $null evaluated as a boolean expression will be treated as $false

I have a filter defined in my profile like this:

filter Skip-Null { $_|?{ $_ } } 

Usage:

$null | skip-null | foreach { ... } 

A filter is the same as a function except the default block is process {} not end {}.

UPDATE: As of PowerShell 3.0, $null is no longer iterable as a collection. Yay!

-Oisin

like image 52
x0n Avatar answered Oct 09 '22 09:10

x0n