Calling a method without parentheses

Late breaking news from PowerShell Conference Europe 2016!!

During PowerShell MVP Chrissy LeMaire’s (@cl) knockout session at PowerShell Conference Europe 2016, “My Journey to 200,000 Rows a Second” (don’t miss the recording; I’ll tweet as soon as it’s available), PowerShell Principal Developer Bruce Payette (@BrucePayette) said that you can call the Where method without parentheses.

Chrissy LeMaire and Bruce Payette at PowerShell Conference Europe.

Chrissy LeMaire and Bruce Payette at PowerShell Conference Europe

“It’s a syntactic twiddle,” he explained, as only Bruce can.

In an exclusive interview, Bruce clarified that, beginning in PowerShell 4.0, you can call ANY method in PowerShell without parentheses if it meets the specified conditions.

The Old Rules: Parentheses are required

Prior to PowerShell 4.0, parentheses were required for any method call, even if the method doesn’t have any arguments, because the PowerShell parser used the parenthesis to identify a method call and distinguish it from a request for a property value.

(Get-Process Notepad).Name   ← Property

(Get-Process Notepad).Kill() ← Method (see the trailing parentheses)

The New Rules

Beginning in PowerShell 4.0, you can call ANY method in PowerShell without parentheses if the method meets the following conditions.

  • The method takes only one argument
  • That argument is a scriptblock

There’s no particular advantage to this other than style, but it’s an interesting stylistic alternative.

This “syntactic twiddle” was designed for the Where and ForEach methods, also introduced in PowerShell 4.0. These magic methods are alternatives to the Where-Object and ForEach-Object cmdlets. They’re faster and have several cool options that make them very valuable. You can read about these new methods here and here.

For example, here is a typical call to the Where method:

$services.Where( {$_.Status -eq 'Running'} )

But, you can also write it like this — without the parentheses. Note that there are no spaces between the “Where” method name and the first curly brace.

$services.Where{$_.Status -eq 'Running'}

Of course, just because you can doesn’t mean that you should. I wouldn’t teach this to beginners, and I probably won’t use it in shared code, but because it’s shown in blogs and you might find it in shared code, it’s important to understand it.

 

In Other News: Why is Out-Null slow?

Bruce also mentioned that, while piping is always slower than the alternatives…

"Hello" | Write-Output

– is slower than –

Write-Output -InputObject "Hello"

… piping to Out-Null should be as quick as redirecting.

However, in Chrissy’s tests, it was much slower.

$(1..1000) > $null       00.21 ms

$(1..1000) | Out-Null    76.21 ms

“That’s a bug,” Bruce explained. “Under the covers, these two expressions are identical, so they should perform the same. When Jason optimized the first form, he probably forgot to optimize the second form.”

You heard it here! Stay tuned for breaking news on the SAPIEN Technologies blog.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at juneb@sapien.com or follow her on Twitter at @juneb_get_help.