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 定義している .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

 

class 定義を書く .ps1 では、base class 定義の後に継承する sub class を書かないと、base class が無いと怒られます。

base class 定義を書いた .ps1 は触りたくないのですが、現状の仕様なので仕方ないですね。

 

関連情報

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

 

 

back.gif (1980 バイト)

home.gif (1907 バイト)

Copyright © MURA All rights reserved.