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

PowerShell class 定義とインスタンスを使用するスクリプトを分離する


PowerShell class はブラックボックスとして使いたいので、class 定義とインスタンスを使用するスクリプトは分離したくなりますようね。
これらを混ぜて書いてしまうと、class の再利用性が下がってしまいますし、何よりコードがゴチャっとなってしまいますから

僕は、class 定義だけを書いた .ps1 を作って、インスタンスを使用する .ps1 で include(.ps1 読み込み)するようにしています。
(C/C++ な人種だったので include って考えがしっくり)

 

class 定義の include

では、どうやって include しているかというと、実は単純で 「.」 を使って .ps1 を実行させています。

実行するといっても、定義しかないので記述内容が取り込まれる動きになります。

こんな感じですね

# Class Include
$IncludeFile = Join-Path $PSScriptRoot "TelnetClient.ps1"
if( -not (Test-Path $IncludeFile) ){
    echo "[FAIL] $IncludeFile not found !"
    exit
}
. $IncludeFile

$TelnetObject = New-Object TelnetClient

 

この手はかなり前から使っていて、複数のスクリプトで共通に使う定数を config.ps1 に書いて読み込むって使い方をしています。

 

継承 class 定義の分離

この考え方の延長で、base class 定義を書いた .ps1 を継承する sub class で include して、インスタンスを使用するスクリプトで sub class を定義した .ps1 を include しようとしたら... この書き方ではうまくいかないんですね...

× うまく動かない例

[BaseClass.ps1]

class BaseClass {
    # 適当な実装
}

[SubClass.ps1]
(base class が無いと怒らる)

# include
$IncludeFile = Join-Path $PSScriptRoot "BaseClass.ps1"
. $IncludeFile

class SubClass : BaseClass {
    # 適当な実装
}

 

なぜ上手くいかないかというと、class がスクリプトスコープなので、sub class と同じ .ps1 に base class が無いと継承できないって PowerShell 5 の仕様なのです。

 

base class と sub class を一緒に書く

簡単に済ませるには、base class 定義している .ps1 に、継承する sub class を書きます。

こんな感じですね

継承 class 定義を分離する例

[class.ps1]

class BaseClass {
    # 適当な実装
}

class SubClass : BaseClass {
    # 適当な実装
}

[main.ps1]

# include
$IncludeFile = Join-Path $PSScriptRoot "class.ps1"
. $IncludeFile

$TestObject = New-Object SubClass

 

base class をモジュールとして分離する

base class 定義を書いたファイルを分離するには、base class をモジュール(.psm1)として分離します。

例えばこんな感じですね

[BaseClass.psm1]

class BaseClass {
    # 適当な実装
}

 

ベースクラスを読み込むには「using module」を使います。

[SubClass.ps1]

# モジュールの読み込み
$ModuleFile = Join-Path $PSScriptRoot "BaseClass.psm1"
using module $ModuleFile

class SubClass : BaseClass {
    # 適当な実装
}

 

main は一緒

[main.ps1]

# include
$IncludeFile = Join-Path $PSScriptRoot "SubClass.ps1"
. $IncludeFile

$TestObject = New-Object SubClass

 

これで base class を物理分離することができます。

 

関連情報

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

 

 

back.gif (1980 バイト)

home.gif (1907 バイト)

Copyright © MURA All rights reserved.