Operations Lab.

PowerShell では存在しないプロパティへアクセスすると $null が返る

leave a comment »

PowerShell では null 値を表す変数として $null が用意されています。

$NULL
$null is an automatic variable that contains a NULL or empty value. You can use this variable to represent an absent or undefined value in commands and scripts.

$null は null 値を表しますので、メソッドやプロパティを持ちません。(当然と言えば当然ですが。)

PS C:\Users\Administrator> $null | Get-Member
Get-Member : get-member コマンドレットにオブジェクトが指定されていません。
発生場所 行:1 文字:9
+ $null | Get-Member
+         ~~~~~~~~~~
    + CategoryInfo          : CloseError: (:) [Get-Member]、InvalidOperationException
    + FullyQualifiedErrorId : NoObjectInGetMember,Microsoft.PowerShell.Commands.GetMemberCommand


PS C:\Users\Administrator> $null.GetType()
null 値の式ではメソッドを呼び出せません。
発生場所 行:1 文字:1
+ $null.GetType()
+ ~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) []、RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

ところが、$null.NonExistant のように存在しないプロパティへアクセスしても、デフォルトではエラーになりません。PowerShell のデフォルトでは、存在しないプロパティへアクセスすると $null が返ります。

When Set-StrictMode is off, uninitialized variables (Version 1) are assumed to have a value of 0 (zero) or $null, depending on type. References to non-existent properties return $null, and the results of function syntax that is not valid vary with the error. Unnamed variables are not permitted.

実際にアクセスしてみると、以下のようになります。

PS C:\Users\Administrator> $null.NonExistant

PS C:\Users\Administrator> $null -eq $null.NonExistant
True

さらにややこしい事に、PowerShell 3.0 のデフォルトの状態で $null の Count プロパティ及び Length プロパティへアクセスすると、$null ではなくて 0 ([int]0)が返ります。

PS C:\Users\Administrator> $null.Count
0

PS C:\Users\Administrator> $null.Length
0

PS C:\Users\Administrator> 0 -eq $null.Count
True

PS C:\Users\Administrator> 0 -eq $null.Length
True

PS C:\Users\Administrator> $null -eq $null.Count
False

PS C:\Users\Administrator> $null -eq $null.Length
False

PS C:\Users\Administrator> $null.Count.GetType()

IsPublic IsSerial Name  BaseType
-------- -------- ----  --------
True     True     Int32 System.ValueType

PS C:\Users\Administrator> $null.Length.GetType()

IsPublic IsSerial Name  BaseType
-------- -------- ----  --------
True     True     Int32 System.ValueType

これは、状況によっては便利なのですが、これでは柔軟すぎる場合もあるかと思います。(一般的に、柔軟になればなるほどバグが混入しやすく、バグの検出や動作確認も難しくなります。)

PowerShell では Strict Mode を設定する事で、上記の動作を変更する事が出来ます。

Set-StrictMode

Establishes and enforces coding rules in expressions, scripts, and script blocks.

The Set-StrictMode cmdlet configures strict mode for the current scope (and all child scopes) and turns it on and off. When strict mode is on, Windows PowerShell generates a terminating error when the content of an expression, script, or script block violates basic best-practice coding rules.

Parameter Set: Version

Set-StrictMode -Version <Version> [<CommonParameters>]

Parameter Set: Off

Set-StrictMode -Off [<CommonParameters>]

Strict Mode Version 2.0 を指定した場合は、存在しないプロパティへアクセスするとエラーが発生するようになります。(デフォルトでは Strict Mode Off となっています。)

PS C:\Users\Administrator> Set-StrictMode -Version 2.0

PS C:\Users\Administrator> $null.NonExistant
このオブジェクトにプロパティ 'NonExistant' が見つかりません。このプロパティが存在することを確認してください。
発生場所 行:1 文字:1
+ $null.NonExistant
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], PropertyNotFoundException
    + FullyQualifiedErrorId : PropertyNotFoundStrict

PS C:\Users\Administrator> $null.Count
このオブジェクトにプロパティ 'Count' が見つかりません。このプロパティが存在することを確認してください。
発生場所 行:1 文字:1
+ $null.Count
+ ~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], PropertyNotFoundException
    + FullyQualifiedErrorId : PropertyNotFoundStrict

PS C:\Users\Administrator> Set-StrictMode -Off

PS C:\Users\Administrator> $null.NonExistant

PS C:\Users\Administrator> $null.Count
0

ちなみに、Version 1.0 の場合は、存在しないプロパティへのアクセスについては Off の場合と同様の動作となります。

PS C:\Users\Administrator> Set-StrictMode -Version 1.0

PS C:\Users\Administrator> $null.NonExistant

PS C:\Users\Administrator> $null.Count
0

Set-StrictMode は設定を行ったセッションの中でのみ有効です。(正確には、該当のスコープ及び子スコープでのみ設定値が有効になります。)コンピュータの環境(グローバルスコープ)へは影響を与えませんので、必要な場合はスクリプトの先頭で Strict Mode を設定しておくと安心です。

広告

Written by kazu

2013/03/11 @ 08:00

カテゴリー: PowerShell

Tagged with

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。