PowerShell 7 で NULL合体演算子(??、??=)が導入されました

2019.11.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

しばたです。
先日リリースされたPowerShell 7 Preview.5の新機能にNULL合体演算子(????=)があります。

本記事ではこの機能について解説します。

?? 演算子

NULL合体演算子(??)は値がNULLでない場合左オペランドの値を返し、NULLの場合は右オペランドの値を返します。
こちらはC#などで導入されているものと同じ機能になります。

# 左オペランドがNULLでない場合は、その値を返す
$left="left is not null."
$right=$null
$left ?? $right

# 右オペランドの値はNULLかどうかは関係ない
$right="right is not null."
$left ?? $right

# 左オペランドがNULLの場合は右オペランドの値を返す
$left=$null
$left ?? $right

??= 演算子

NULL合体割り当て演算子(??=)は左オペランドがNULLの場合のみ、右オペランドの値を代入します。
こちらもC#などで導入されているものと同じ機能になります。

# 左オペランドがNULLの場合のみ代入可能
$right="value1"
$left ??= $right

# 左オペランドは先の代入でNULLでないため更新できない
$right="value2"
$left ??= $right

【注意事項】 =?? でないので間違えない様に

地味に厄介な問題なのですが、NULL合体割り当て演算子は ??= であり、 =?? ではありません。
=??=を先にもってきてしまうと、

$left = (?? $rigth)

の様に評価され、??を何らかの関数やエイリアスに割り当てている場合は評価・実行されてしまいます。

私の環境ではposh-gitモジュールが??Invoke-NullCoalescingのエイリアスに割り当ててしまっていたため上図の様な結果になり、しばらく原因が分からず困りました...

こちらはposh-gitのバージョンをVer.1.0.0-beta.1以降にすると解消されます。(#427)

補足 : PowerShellにおける"NULL"とは何か?

最後に補足としてPowerShellにおけるNULLについて軽く触れておきます。

以前個人ブログで触れたのですが、PowerShellではNULLとされるものについて大きく$nullAutomationNullの二種類あり、ざっくりと

  • $null : .NET FrameworkにおけるNULLをPowerShellで明示するための値
  • AutomationNull : PowerShellにおけるVoidを表現するための値。評価を打ち切るための値でもある

の様に大別されます。

また、.NET FrameworkにはRDBMSのNULL値を表現するSystem.DBNullが存在しておりPowerShellからも利用可能でした。
このDBNullについて、これまではPowerShellとしては特別視していなかった(すなわち$nullAutomationNullとは別の単なるシングルトンなオブジェクトとして評価されていた)のですが、PowerShell 7 Preview.3より$nullと同様に扱う様に仕様変更されています。

本記事で触れたNULL合体演算子では上記3つの値全てをNULLとして扱います。

【2020.04.24追記】
DBNull$nullと同様に扱う仕様変更についてはPowerShell 7 RC.2でGAリリース直前に際し戻されたため、DBNullはPowerShell上では通常の1オブジェクトとして取り扱われます。