tech.guitarrapc.cóm

Technical updates

PowerShell v5 の新機能紹介 - PowerShell で Class構文が利用可能になります

今回も前回に続き PowerShell v5 をコアとする Windows Management Framework 5.0 Preview September 2014 (v5.0) の機能詳細を触りつつ、何が変わるのかお伝えできればと思います。

  • Develop with classes in Windows PowerShell

ついにクラスが PowerShell で操作できます。やったー!

  • 追記 : PowerShel v5 がリリースされました

tech.guitarrapc.com

  • 過去の記事はこちら

目次

できること

簡単にいうと、いわゆる object-oriented なスタイルでの記述です。例を挙げると、

  • Enumの宣言
  • Class構文
  • Properties
  • Methods
  • Inheritance (継承)

などなど。

これを使って、

  • DSC Resource の記述
  • 独自型をPowerShel Script だけで規定、利用
  • 規定した型のデバッグがPowerShellで買おうに
  • 例外処理も、正しく適切なレベルで行えるように

できないこと

現状まだできないことは多くあります。

  • Property が public しかなく、ReadOnly などはできない
  • Get-DSCResourceでは、Class構文で書かれたリソースを検知できない
  • DSC エンジンキャッシュが、PowerShellスクリプトモジュールに向けて作りこまれているため、DebugModeを有効にする必要があります
  • New-Object でのクラス生成ができず、Static Method である [ClassName]::New() を使う必要がある

カスタムタイプ

規定できるものをさくっと見てみましょう。

Class Keyword

.NET Framework に基づく新しいクラスを規定します。

メンバーはパブリックですが、パブリックな範囲は 「モジュールスコープ」に限定されています。

現段階では、 スクリプトやモジュールで規定したMyClassクラスを、モジュール/スクリプトの外部から[MyClass]のような形式で検知することはできません。

つまり、文字列からクラスを検知できないため、New-Object を使うことができません。

構文

Class MyClass
{
}
Enum Keyword と列挙

もし July Preview を使っていた人がいたら破壊的変更になります。 Enumのデリミタが,ではなく、改行になりました。

ついにきました。Enumです。PowerShell では、Enumが相当活躍するので、独自に規定できるのは大事です。

従来は、Class同様に C# で書いて、Add-Type で読み込む必要がありました。

たとえば、Valentia ではこういった型を持っています。

これが、Enumキーワードを使えばこんな感じで規定できます。

素晴らしいです。もう Tyr{}Catch{} も不要です。AppDomainで苦しまずにすみます。

構文

Enum MyEnum
{
}

制限

現状は、Enumerator Value はEnumキーワード実行時に決まっている必要があります。

つまり、何かのコマンドの結果とすることはできません。

たとえば、こうはできます。

Enum Colour
{
    Blue = [int]::MaxValue
}

が、こうはできません。

Enum Colour2
{
    Yellow = (Get-childItem).Count
}

このような警告がでます。

f:id:guitarrapc_tech:20140908071256p:plain

算術結果はサポートしているのでこういうのはありです。

Enum SomeEnum { Max = 42 }
Enum OtherEnum { Max = [SomeEnum]::Max + 1 }
Import-DscResouce

これまでもキーワードでしたが、正しく Dynamic Keyword となりました。

PowerShell は、このキーワードを使って、Rootモジュールを走査して [DSCResource()] 属性をもったクラスを検知します。

Properies

ModuleInfo に ImplementingAssembly フィールドが追加されました。

これは、スクリプトモジュール内のクラスや、C# Cmdletで書かれた バイナリモジュールのためのです。なので、 ModuleType が Manufest、つまり psd1 だとでません。

ImplementingAssembly フィールドをリフレクションすると、どんなリソースがモジュールに含まれるかわかります。つまり、PowerShell や他の言語からどんなリソースが存在しているか調べれるということです。

まさに、chef のため(?) と思えそうな機能ですね!

Initializing

フィールドの初期化として

[int] = 5;

などとかくこともできます。

Static

Static がサポートされているので、こうかけます。

Static [int] = 5;

やったね。

f:id:guitarrapc_tech:20140908072353p:plain

すべてPublic

現状はPublicのみです(えー

Classの スコープが Lexical Scope なので、クラス外部からの影響やクラス外部への影響はありません。

関数 Function{} や ScirptBlock {} で悩まされたあの問題が完全回避できるのはうれしいですね。

しかし、すべて Publicかぁ。

Constructor

Constructor も利用可能です。

C# 同様にクラスと同名である必要があります。また、overload可能です。

Static Constructor も利用可能で、Static Property は Static Constructor の前に初期化されます。

同様に、インスタンスプロパティは、non-Static Constructor の前に初期化されます。

制限

現状は、C#にあるようなConstructor を別の Constructor から呼ぶシンタックスはないので次のような記述はできません。

: this()
インスタンス生成

クラスのインスタンス生成は、従来の New-Objectがまだ使えないのでスタティックメソッドを利用します。

$MyClass = [MyClass]::new()

これで、$MyClass でもにょれます。

Constructor の例を見てみましょう。

this がないのは、現状の制限です。

Method

PowerShell の Class構文における Method は、ScriptBlock つまり匿名コンストラクタを使っています。

ScriptBlock の End節のみ使っているのが特徴です。型付けできるのでいい感じです。

属性

Class には、特定の属性が用意されています。

  • DscResource
  • DscResourceKey
  • DscResourceMandatory

です。いずれも DSC Resource として組む場合のキーになるものです。

スコープ

先ほど説明したとおり、Lexical Scope です。

リリースノートのサンプルはこんな感じですね。

まとめ

どうでしょうか。少しはとっつきやすくなったでしょうか。

初めは Def とかあって、Ruby... え。でしたが、リリースノートからは C# を意識しているようです。

Cmdlet を書け?はい。でも、まぁうれしいと思います。