Home > Windows にまつわる e.t.c.

超簡単な PowerShell Class の使い方(その1)


PowerShell Vertion 5 から PowerShell での Class がサポートされました。

まずは脱線から(おぃ)
その昔、僕は C でコードを書いていました。まだ世の中に C++ が生まれる前って石器時代の話ですけど ww
当時オブジェクト指向プログラミング言語が生まれ始めていたのですが、それが C にもやってきて C++ が登場したのです。
ここで新たに登場したのが Class
新しもの好きなので速攻で食いついて C++ を使い始めて Class の便利さを知ったのですが、他のプログラマーにクラスを説明するのが大変で...

そんなこんなで、従来の PowerShell スタイルの .ps1 を書いている方向けに、超簡単な PowerShell class 説明書いてみることにしました。

 

Class のざっくり説明

オブジェクト指向プログラミングに馴染みが無いと、「Class って何? それって食べられるの?」ってことになりそうなので、まずはざっくりクラスの概要から。

 

荒っぽく言ってしまうと、Class は拡張された function です。

 

何が拡張されたかと言うと、内部に値(プロパティ)を持ち、メソッドで操作が出来るようになりました。
(以降 「内部データ」 と 「プロパティ」 の2つの言葉が出てきますが、文脈によって使い分けているだけで同じ意味です)

この class をメモリ上にインスタンス化させたのがオブジェクトです。

 

こんな説明だと「んで、具体的には??」ですよね

実は PowerShell を使っている方は、オブジェクトを普通に使っているのです。

PS D:\> $TextData = Get-Content D:\temp\test.txt
PS D:\> $TextData.Length
4

 

この時の $TextData がオブジェクトで、Length がメソッドです。

PowerShell 4 までは、出来合いのオブジェクトしか使えなかったのですが、PowerShell 5 からは、class を使って自前のオブジェクトが作れるようになったのです。

 

初めての class

どう動くのかを見るのが手っ取り早いですね。

まずは、お約束の Hello World

# クラス定義
class TestClass{
    [string] hoge(){
        return "Hello PowerShell Class !!"
    }
}

 

これを動かすには以下のようにします。

# インスタンス化
$TestObject = New-Object TestClass

# メソッドの実行
$TestObject.hoge()

 

PS D:\> # クラス定義
PS D:\> class TestClass{
>>     [string] hoge(){
>>         return "Hello PowerShell Class !!"
>>     }
>> }
PS D:\>
PS D:\> # インスタンス化
PS D:\> $TestObject = New-Object TestClass
PS D:\>
PS D:\> # メソッドの実行
PS D:\> $TestObject.hoge()
Hello PowerShell Class !!
PS D:\>

 

New-Object を使わない場合は、こんな感じで使います。

# インスタンス化
$TestObject = [TestClass]::new()

# メソッドの実行
$TestObject.hoge()

なんだか、.NET Framework を使う時に似てますね。

 

超簡単な class の使い方

PowerSehll 5 の Class はまだ過渡期なので今後出来る事が増えてくると思われますが、現状の仕様でも .ps1 をちょいちょい書いている方に便利な事が多いので、簡単な「クラス、プロパティ、メソッド」の使い方を解説します。
(超簡単説明なので基本的な事だけ。これ以外の説明はバッサリ省略していますw)

ここから先は、PowerShell プロンプトへのコピペだと正しく構文解釈してくれない(エラーになる)ので、.ps1 にして実行します。

 

内部データ(プロパティ)を使った簡単な計算をしてみましょう。

[D:\temp\test1.ps1]

# クラス定義
class TestClass2
{
    # 内部データ
    [int] $Data

    # 内部データに加算して return するメソッド
    [int] Add([int]$Indata){
        
        # 内部データに加算
        $this.Data += $Indata
        
        # 内部データ return
        return $this.Data
    }
}

# インスタンス化
$TestObject2 = New-Object TestClass2

# 10 を加算
$TestObject2.Add(10)

# 20 を加算
$TestObject2.Add(20)

 

これを実行するとこのようになります。

PS D:\> D:\temp\test1.ps1
10
30
PS D:\>

 

class 内から内部データにアクセスする場合は、内部データを表現する $this を明示的に書く必要がありますが、普通に内部データにアクセスすることができます。

ちなみに、メソッド内で他のメソッドを呼ぶときも、$this.Add のようにメソッドに $this を明示的に書くと普通にメソッドとして使用する事が出来ます。

 

これを function で書いた場合と比較してみましょう。

[D:\temp\test2.ps1]

function TestFunction( $Indata ){

    # 内部データ?
    [int] $Data

    # 内部データに加算
    $Data += $Indata

    # 内部データ return
    return $Data
}

# 10 を加算?
TestFunction 10

# 20 を加算?
TestFunction 20

 

PS D:\> D:\temp\test2.ps1
0
10
0
20
PS D:\>

 

function はデータを保持しないので、常に変数が初期化されてしまいます。

function でこういった処理をする場合は、内部データに相当する $Data を外出し管理するのが常套手段ですね。

[D:\temp\test3.ps1]

function TestFunction2( $Data, $Indata ){

    # 内部データに加算
    $Data += $Indata

    # 内部データ return
    return $Data
}

# 10 を加算
$Data = TestFunction2 0 10
echo $Data

# 20 を加算
$Data = TestFunction2 $Data 20
echo $Data

 

class を使うと、処理に必要なデータは class に管理を任せる事が出来るで、すっきりと記述することができます。

今回の例では、内部データの初期値なし定義しかしていませんが、[int] $Data2 = 20 のように初期値を設定も可能です。

 

 

プロパティへのアクセス

先ほど書いた TestClass2 の内部データ(プロパティ)にアクセスしてみましょう

[D:\temp\test4.ps1]

# クラス定義
class TestClass2
{
    # 内部データ
    [int] $Data

    # 内部データに加算して return するメソッド
    [int] Add([int]$Indata){
        
        # 内部データに加算
        $this.Data += $Indata
        
        # 内部データ return
        return $this.Data
    }
}

# インスタンス化
$TestObject2 = New-Object TestClass2

# 10 を加算
$TestObject2.Add(10)

# 内部データの表示
$TestObject2.Data

 

PS D:\> D:\temp\test4.ps1
10
10
PS D:\>

 

PowerShell v5 class の内部データは public なので、class の外から値をセットする事が出来てしまいますが、値を直接セットするコードを書いてしまうと、折角 class に内部データ管理を任せいる意味が無くなってしまうので、内部データは class の外から更新せず、更新用のメソッドを作ることをお勧めします。

そういった意味では、内部データの直接読み取りもせずに、読み取り用のメソッドを作るのが良いですね。

一般的なオブジェクト指向言語では、内部データを Read Only にするとか隠蔽して class の外部から操作できなくする事が出来るのですが、PowerShell v5 class ではこれらがサポートされていません。(今後サポートされると予想)

 

コンストラクタ

内部データを持たせる事が出来ると言う事は、内部データに初期値をセットする必要がありますね。

内部データに初期値をセットするメソッドを書くとこんな感じになります。

[D:\temp\test5.ps1]

# クラス定義
class TestClass3
{
    # 内部データ
    [int] $Data

    # 初期値のセット
    [void] Set([int]$Indata){
        
        # 内部データにセット
        $this.Data = $Indata
    }


    # 内部データに加算して return するメソッド
    [int] Add([int]$Indata){
        
        # 内部データに加算
        $this.Data += $Indata
        
        # 内部データ return
        return $this.Data
    }
}

# インスタンス化
$TestObject3 = New-Object TestClass3

# 初期値 10 をセット
$TestObject3.Set(10)

# 20 を加算
$TestObject3.Add(20)

 

PS D:\> D:\temp\test5.ps1
30
PS D:\>

 

あれ? .NET Framework を使う場合、New-Object 時に初期値をセット出来ますけど、PowerShell では出来ないの?

はい 出来ますょ

class で初期値をセットするメソッドをコンストラクタと呼んでおり、PowerShell class でもコンストラクタがサポートされています。

コンストラクタを定義する場合は、Class 名と同じ名前のメソッドを作成します。

[D:\temp\test6.ps1]

# クラス定義
class TestClass4
{
    # 内部データ
    [int] $Data

    # コンストラクタ(初期値のセット)
    TestClass4([int]$Indata){
        
        # 内部データに初期値をセット
        $this.Data = $Indata
    }

    # 内部データに加算して return するメソッド
    [int] Add([int]$Indata){
        
        # 内部データに加算
        $this.Data += $Indata
        
        # 内部データ return
        return $this.Data
    }
}

# インスタンス化(初期値 10 をセット)
$TestObject4 = New-Object TestClass4(10)

# 20 を加算
$TestObject4.Add(20)

 

PS D:\> D:\temp\test6.ps1
30
PS D:\>

 

これ以外にも簡単に使えて便利な機能がありますので、「超簡単な PowerShell Class の使い方(その2)」 も見てください

 

関連情報

超簡単な PowerShell Class の使い方(その2/オーバーロード)
http://www.vwnet.jp/Windows/PowerShell/2017082101/PSv5Class02.htm

超簡単な PowerShell Class の使い方(その3/static)
http://www.vwnet.jp/Windows/PowerShell/2017082201/PSv5Class03.htm

超簡単な PowerShell Class の使い方(その4/継承)
http://www.vwnet.jp/Windows/PowerShell/2017082301/PSv5Class04.htm

超簡単な PowerShell Class の使い方(その5/スコープ)
http://www.vwnet.jp/Windows/PowerShell/2017082302/PSv5Class05.htm

超簡単な PowerShell Class の使い方(その6/まとめ)
http://www.vwnet.jp/Windows/PowerShell/2017082401/PSv5Class06.htm

PowerShell Class
http://www.vwnet.jp/Windows/etc.asp#PowerShell_Class

PowerShell クラスを使用したカスタム型の作成Creating Custom Types using PowerShell Classes | Microsoft Docs
https://docs.microsoft.com/ja-jp/powershell/wmf/5.0/class_overview

 

 

back.gif (1980 バイト)

home.gif (1907 バイト)

Copyright © MURA All rights reserved.