オブジェクトの動的な拡張については、PythonやJavaScriptといった動的言語に慣れている方にはお馴染みですね。PowerShellでは、Add-MemberコマンドレットやPSObjectを利用してオブジェクトを拡張できます。まずは、Add-Memberコマンドレットを使用する例です。
PS > $x = 1
PS > $x | Add-Member ScriptMethod Greet { "Hello, my number is $this." }
PS > $x.Greet()
[System.Int32] に 'Greet' という名前のメソッドが含まれないため、メソッドの呼び出しに失敗しました。
失敗してしまいました。Add-Memberコマンドレットを使用する場合、拡張したいオブジェクトがPSObjectかどうか(-is [PSObject]
)に注意が必要です。PSObjectならばいいのですが、PSObjectでない場合はAdd-MemberのpassThruスイッチを指定してAdd-Memberが値を返すようにしないと拡張したオブジェクトを使用できません。
PS > $x -is [PSObject]
False
PS > $x = $x | Add-Member -passThru ScriptMethod Greet { "Hello, my number is $this." }
PS > $x.Greet()
Hello, my number is 1.
PS > $x -is [OSObject]
True
Add-Memberは入力が非PSObjectだった場合PSObjectでラップして拡張するので、新しく作られたPSObjectをpassThruスイッチを指定することで取得するのです。$xはPSObjectでラップされたので、さらにオブジェクトを拡張するときは-passThruは必要ありません。
つづいてPSObjectを利用してオブジェクトを拡張します。これには、PSObjectプロパティを使用します。PSObjectプロパティは特殊で、PSObjectでないオブジェクトに対してPSObjectプロパティを取得しようとすると、エラーにならずにそのオブジェクトがPSObjectでラップされます。例を見てみましょう。
PS > $x = 1
PS > $x -is [PSObject]
False
PS > $x.PSObject
Members : {CompareTo, Equals, GetHashCode, ToString...}
Properties : {}
Methods : {CompareTo, Equals, GetHashCode, ToString...}
ImmediateBaseObject : 1
BaseObject : 1
TypeNames : {System.Int32, System.ValueType, System.Object}
PS > $x -is [PSObject]
True
最初は$xはただのInt32であるため$x -is [PSObject]
はFalseを返しますが、一度PSObjectプロパティにアクセスしてからは$x -is [PSObject]
がTrueを返すようになっていますね。
それでは、$xを拡張してみましょう。先ほどと同様に、Greetメソッドを追加します。
PS > $method = New-Object System.Management.Automation.PSScriptMethod `
>> Greet, { "Hello, my number is $this." }
>>
PS > $x.PSObject.Members.Add($method)
PS > $x.Greet()
Hello, my number is 1.
メソッドを追加できました。オブジェクトの拡張には基本的にはAdd-Memberコマンドレットを使用しますが、PSObjectプロパティを利用するやり方はプログラマには馴染みやすいかもしれませんね。
posted by bakemoji at 14:53|
Comment(0)
|
TrackBack(0)
|
PowerShell
|

|