+ All Categories
Home > Technology > Power shell で DSL

Power shell で DSL

Date post: 25-Jun-2015
Category:
Upload: urasandesu
View: 1,274 times
Download: 1 times
Share this document with a friend
Popular Tags:
37
PowerShell でC# でででででででででで JIT でででででで C++ ででででででで でででででででででででででででででででででででで DSL ででででででで でで で Twitter: @urasandesu Blog: http://urasandesu.blogspot.jp/
Transcript
Page 1: Power shell で DSL

PowerShell で、

C# で書かれたメソッドの JIT をフックする C++ のライブラリのコードを自動生成するテンプレートエンジンのための

DSL を実装してみた

杉浦 彰Twitter: @urasandesu

Blog: http://urasandesu.blogspot.jp/

Page 2: Power shell で DSL

自己紹介

Page 3: Power shell で DSL

自己紹介

名前 杉浦 彰( Akira Sugiura )

職業 SE

画像情報管理のためのソフトウェア開発( C#/WPF ) 年齢

今年で 0x20 歳 オンラインでの活動

Twitter: @urasandesu

Blog: http://urasandesu.blogspot.jp/

.NET(CLR) の基礎技術や、開発のための基盤に関心 PE

ファイル / メタデータ /IL/ 厳密な名前 /GAC/ プロファイラ /AppDomain/CodeDOM/  動的アセンブリ / 式木 /DLR

Page 4: Power shell で DSL

自己紹介

オンラインでの活動(続き) Prig(Prototyping jig)

単体テストのためのテストダブル生成フレームワーク。 C# (に限らず、 .NET 上で動作する言語)で書かれたプログラムの JIT をフッ

クして、実行時に処理を入れ替える。 構想含めると 5 年近く、 7 回ほど作り直ししてますが、まだ動きません・・・。 やっと入れ替え前のメソッドの中身をコピーして、それを使って上書きして、元の

処理がそのまま動くよね、ってところ。

似たようなことができるもの Microsoft Fakes/Typemock Isolator/Telerik JustMock

??

今回の PowerShell 勉強会のネタにはなりました!

Page 5: Power shell で DSL

DSL とは?

Page 6: Power shell で DSL

DSL とは?

ドメイン特化言語 ( 英 : domain-specific programming language)

特定のタスク向けに設計されたコンピュータ言語。 一種類のタスクをうまく実行することに集中。 ポリシー

その領域(ドメイン)をより表現しやすくする。 そのドメインにおいては、仕様変更に対して最小限の記述で済ませられる。 包括的ではない。

Page 7: Power shell で DSL

DSL とは?

ドメイン特化言語の例 Unix シェルスクリプト

ファイル操作、プログラム実行、テキストの印刷に特化。

※ シェルスクリプトをベースにした PowerShell も、 DSL の一つ!

他にも、 SQL や HTML 、 Wiki のマークダウンなど。

bash[~]$ cat tel | sed 's/\(...\)\(....\)\(....\)/\1-\2-\3/'090-1111-2222080-9876-9876090-2222-1111bash[~]$

PS ~> gc tel | % { $_ -replace '(...)(....)(....)', '$1-$2-$3' }090-1111-2222080-9876-9876090-2222-1111PS ~>

Page 8: Power shell で DSL

DSL とは?

ドメイン特化言語の対義語としてあるのが、汎用言語( 英 : general-purpose programming language)

Page 9: Power shell で DSL

DSL とは?

汎用言語は工具箱 様々なタスク向けのツール群が含まれている。

Page 10: Power shell で DSL

DSL とは?

ドメイン特化言語は電動ドリル 穴を空けることにかけては強力なツール。

自分の工具箱を見て、もっと良いドリルが必要だと思ったら、ドメイン特化言語を探してみたほうが良いかも!

Page 11: Power shell で DSL

DSL とは?

無かったら?

Page 12: Power shell で DSL

自作ライブラリ紹介

Page 13: Power shell で DSL

自作ライブラリ紹介

PSAnonym

目的問わず利用できる PowerShell 向けの補足的なライブラリ。 公開中: https://github.com/urasandesu/PSAnonym

Swathe.Automation

C# で書かれたメソッドの(略 公開準備中・・・

残念ながら・・・ 今のところ PowerShell 2.0 上でしか動きません (>_<)

主にパフォーマンス向上のため、アンドキュメントな API 呼び出しや動的アセンブリを使った非公開処理呼び出しを多用しているため。

Page 14: Power shell で DSL

自作ライブラリ紹介

Demo

Page 15: Power shell で DSL

自作ライブラリ紹介

PSAnonym.Linq

PowerShell で LINQ っぽいものを書けるようにするモジュール。 PowerShell 2.0 でよく上げられる Select-Object の -First スイッチ問

題や、フロー制御構文の外で break を記述すると、スクリプト全体が止まってしまう問題の解決が動機。

よく使うクエリ( Select/SelectMany/Where/Skip/Take/Any/Zip など)を中心に、現在 27 クエリを実装。

例PS ~> QRange 1 10 | QSelect { $1 * $1 } | QToArray149162536496481100

Page 16: Power shell で DSL

自作ライブラリ紹介

PSAnonym.Prototype

PowerShell を、プロトタイプベース&多重継承サポートなオブジェクト指向言語として使えるようにするモジュール。

PowerShell も DSL の一つ。クラス定義などは本来不要。 テンプレートエンジンに、 PowerShell の強力なテキスト処理系はもって

こい。しかし、実際に使うには、「状態を持ち、自分自身を操作できる」、「基底 – 派生関係を持ち、生成の対象によって一部の振る舞いを変えることができる」といったクラスのような存在が欲しくなる。

例PS ~> $animal1 = Prototype Animal | AbstractMethod CryPS ~> $dog1 = $animal1 | Prototype Dog | OverrideMethod Cry { ' わんわん ' }PS ~> $cat1 = $animal1 | Prototype Cat | OverrideMethod Cry { ' にゃーにゃー ' }PS ~> $chimaira1 = $dog1, $cat1 | Prototype Chimaira -Force | >> OverrideMethod Cry { $Dog.Cry() + $Cat.Cry() }PS ~> $animals = $dog1, $cat1, $chimaira1PS ~> $animals | % { $_.Cry() }わんわんにゃーにゃーわんわんにゃーにゃー

Page 17: Power shell で DSL

自作ライブラリ紹介

Swathe.Automation

C++ のヘッダーファイルと実装ファイルの依存関係管理を、自動生成による力業で解決するための設定 DSL 。

Swathe.ps1

*Fwdh.Template.ps1

*h.Template.ps1

*hpp.Template.ps1

*cpp.Template.ps1テンプレートファイル

依存関係の定義ファイル New-xx.ps1

VC++ プロジェクト毎のテンプレートエンジン

xx.vcxproj

*Fwd.h

*.h

*.hpp

*.cpp

xx.vcxproj.filters

C++ ヘッダー / 実装ファイル

VC++ プロジェクトファイル

Page 18: Power shell で DSL

自作ライブラリ紹介

# -----------------------------------------------------------------------------------------------# # Declaration # Import SimpleHeapProviderImport SmartHeapProviderImport PersistableHeapProvider・・・ Declare $RootDirectory Urasandesu Swathe / Hosting BaseClass / Base HostInfo / Fwd .hDeclare $RootDirectory Urasandesu Swathe / Hosting BaseClass / Base HostInfo / / .hDeclare $RootDirectory Urasandesu Swathe / Hosting BaseClass / Base HostInfo / / .hppDeclare $RootDirectory Urasandesu Swathe AutoGen Hosting BaseClass / Base HostInfo / / .cpp・・・## -----------------------------------------------------------------------------------------------  # -----------------------------------------------------------------------------------------------# # Dependency #DependsOn BaseHostInfoFwdH DefaultHostInfoApiHolderFwdHDependsOn BaseHostInfoH HostInfoFacadeH BaseHostInfoFwdHDependsOn BaseHostInfoHpp BaseHostInfoHDependsOn BaseHostInfoCpp BaseHostInfoHpp DefaultHostInfoApiHolderH DefaultHostInfoPimplApiHolderH・・・## -----------------------------------------------------------------------------------------------

Swathe.ps1

依存関係の定義ファイル

Page 19: Power shell で DSL

自作ライブラリ紹介

@"#pragma once#ifndef $($Me.IncludeGuard)#define $($Me.IncludeGuard) "@ + $({ $Me.DependentHeadersWithoutCommon } | QSelect { @"#ifndef $($1.IncludeGuard)#include <$($1.PathWithoutRoot)>#endif"@ } | QToParagraphParagraph) + @" namespace $($Me.Namespaces[0]) { namespace $($Me.Namespaces[1]) { namespace $($Me.Function) {   template<class ApiHolder> class $($Me.Name) { public: $($Me.ClassFacadeH.BeginTypedefAlias) $($Me.ClassFacadeH.DeclareTypedefAlias) $($Me.ClassFacadeH.EndTypedefAlias)・・・ }; }}}} // namespace $($Me.Namespaces[0]) { namespace $($Me.Namespaces[1]) { namespace $($Me.Function) {  #endif // $($Me.IncludeGuard)"@

*Fwdh.Template.ps1

*h.Template.ps1

*hpp.Template.ps1

*cpp.Template.ps1テンプレートファイル

Page 20: Power shell で DSL

自作ライブラリ紹介

#pragma once#ifndef URASANDESU_SWATHE_HOSTING_BASECLASS_BASEHOSTINFO_H#define URASANDESU_SWATHE_HOSTING_BASECLASS_BASEHOSTINFO_H #ifndef URASANDESU_SWATHE_AUTOGEN_HOSTING_CLASSFACADE_HOSTINFOFACADE_H#include <Urasandesu/Swathe/AutoGen/Hosting/ClassFacade/HostInfoFacade.h>#endif #ifndef URASANDESU_SWATHE_HOSTING_BASECLASS_BASEHOSTINFOFWD_H#include <Urasandesu/Swathe/Hosting/BaseClass/BaseHostInfoFwd.h>#endif namespace Urasandesu { namespace Swathe { namespace Hosting {   template<class ApiHolder> class BaseHostInfo { public: SWATHE_BEGIN_HOST_INFO_FACADE_TYPEDEF_ALIAS SWATHE_DECLARE_HOST_INFO_FACADE_TYPEDEF_ALIAS SWATHE_END_HOST_INFO_FACADE_TYPEDEF_ALIAS・・・ }; }}}} // namespace Urasandesu { namespace Swathe { namespace Hosting {  #endif // URASANDESU_SWATHE_HOSTING_BASECLASS_BASEHOSTINFO_H

*Fwd.h

*.h

*.hpp

*.cpp

C++ ヘッダー / 実装ファイル

Page 21: Power shell で DSL

自作ライブラリ紹介

<?xml version="1.0" encoding="utf-8"?><Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">・・・ <ItemGroup> <ClCompile Include="Urasandesu\Swathe\AutoGen\Hosting\BaseClass\BaseHostInfo.cpp" />・・・ </ItemGroup> <ItemGroup> <ClInclude Include="Urasandesu\Swathe\Hosting\BaseClass\BaseHostInfo.h" /> <ClInclude Include="Urasandesu\Swathe\Hosting\BaseClass\BaseHostInfo.hpp" /> <ClInclude Include="Urasandesu\Swathe\Hosting\BaseClass\BaseHostInfoFwd.h" />・・・ </ItemGroup></Project>

xx.vcxproj

xx.vcxproj.filters

VC++ プロジェクトファイル

Page 22: Power shell で DSL

私のケース

Page 23: Power shell で DSL

私のケース

なぜこんなものを? Prig は C++ がメイン開発言語。

マネージコードの JIT をフックするので、直接マネージコードを使うことはできない。 最初からある程度の規模を予想。

主なクラス・・・ランタイムを動かすホスト、 PE ファイルのリーダー / ライター、ランタイム情報へのアクセッサ、 GAC とのやりとりを行う各種クラス、メタデータ情報を表す各種クラス( Assembly/Module/Type/Method/Field/Property/Event … )、プロファイリング情報を表す各種クラス、厳密な名前を扱うための各種クラス、・・・。

上記のものについて、生存期間が同じもの達に対して、その管理クラスを・・・。 さらにメモリ管理もある程度グルーピングして、その生成・破棄クラスを・・・。 あれ? 1,000 クラスとか普通に超えるんじゃね?

ヘッダーファイルと実装ファイル間の依存関係をうまく管理できないと詰む!

Page 24: Power shell で DSL

私のケース

C++ の依存関係のおさらい コンパイル単位につき、

宣言はいくつでも 定義は 1 つ

#include の順番に依存   するのはまずい インクルードガード

#pragma once#ifndef URASANDESU_SWATHE_HOSTING_BASECLASS_BASEHOSTINFO_H#define URASANDESU_SWATHE_HOSTING_BASECLASS_BASEHOSTINFO_H

#ifndef URASANDESU_SWATHE_HOSTING_BASECLASS_BASEHOSTINFOFWD_H#include <Urasandesu/Swathe/Hosting/BaseClass/BaseHostInfoFwd.h>#endif namespace Urasandesu { namespace Swathe { namespace Hosting {   template<class ApiHolder> class BaseHostInfo {・・・ }; }}}} // namespace Urasandesu { namespace Swathe { namespace Hosting {  #endif // URASANDESU_SWATHE_HOSTING_BASECLASS_BASEHOSTINFO_H

✔一意になるように!ファイルパスや名前空間から生成するのが良いみたい

Page 25: Power shell で DSL

私のケース

簡単にヘッダーファイル / 実装ファイル間の依存関係管理できるツールって無い? Microsoft : Visual C++ 開発用ツール /依存関係グラフ

C コードおよび C++ コードに対する依存関係グラフの生成機能! Visual Studio Ultimate が必要。個人で使うには

GNU project : gcc

-MD スイッチで、依存関係一覧を make 向けのフォーマットで出力可能! 変更しても書き戻せない

Eclipse : C/C++ Development Tooling (CDT)

今調べると、 Java の “ Organize Imports” みたいな感じで、” Organize Includes” ができるようになってる!?

うまく動かせず

・・・( ´ ・ ω ・`)

・・・( ´ ・ ω ・`)

・・・( ´ ・ ω ・`)

Page 26: Power shell で DSL

私のケース

依存関係の管理が必要になるところは、汎用テンプレートエンジンを使って自動生成で同期するしかない・・・ Microsoft : T4(Text Template Transformation Toolkit)

Visual Studio で使えるテンプレートエンジン。 C#/Visual Basic 向け。 C++ は

Apache : Velocity

Java の汎用テンプレートエンジン。業務でも使ったことあり。 .NET 向けのプロジェクトに Java は

Microsoft : Razor

元々は ASP.NET MVC の View エンジンとして開発されたテンプレートエンジン。 Matthew Abbott 氏を中心に、普通のライブラリのように使えるもの( RazorEngine )が開

発されている。RazorEngine 、今見直すとこれで全然良い!ヾ ( ゚∀゚ ) ノ当時は、「 ASP.NET」の時点で候補から外れてたみたい・・・

・・・( ´ ・ ω ・`)

・・・( ´ ・ ω ・`)

Page 27: Power shell で DSL

私のケース

無かった (` ・ ω ・ ´) キリッ

(´-`).oO( 見つけられなかったとも言う・・・ )

Page 28: Power shell で DSL

PowerShell と DSL

Page 29: Power shell で DSL

PowerShell と DSL

PowerShell インアクション Soul of a New Language

言語デザイナーの一人でもあるBruce Payette が解説。

ポリシーや、なぜこうなってるのかが記載してあり納得感。

第 8章 スクリプトブロックとオブジェクト には、「メタプログラミング」や「言語の拡張」といった心躍る内容がヾ ( ゚∀゚ ) ノ

Page 30: Power shell で DSL

PowerShell と DSL

知っておくと良いかも?キーワード 解析モード Invoke-Expression

パイプライン スクリプトブロック スコープ モジュール types.ps1xml

クロージャ PSCustomObject

PSObject

PSMemberInfo

Runspace

AppDomain

Page 31: Power shell で DSL

終わりに

Page 32: Power shell で DSL

終わりに

Page 33: Power shell で DSL

終わりに

Page 34: Power shell で DSL

終わりに

Page 35: Power shell で DSL

参考文献

Page 36: Power shell で DSL

参考文献

ドメイン固有言語 - Wikipedia

http://ja.wikipedia.org/wiki/%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E5%9B%BA%E6%9C%89%E8%A8%80%E8%AA%9E

USP友の会 :第3 回シェル芸爆破デスマッチ勉強会&第21 回餃子爆破定例会やってきたhttp://www.usptomo.com/PAGE=20130217USPSTUDY

「第3 回シェル芸爆破デスマッチ勉強会&第21 回餃子爆破定例会やってきた」を Powershell でやってみた - tech.guitarrapc.com

http://tech.guitarrapc.com/entry/2013/02/18/070226

#include <rules> | What your mother never told you about graphics development

http://zeuxcg.org/2010/11/15/include-rules/

依存関係グラフでのコード依存関係の視覚化 - MSDN

http://msdn.microsoft.com/ja-jp/library/dd409453(v=vs.110).aspx

GCC, the GNU Compiler Collection - GNU Project - Free Software Foundation (FSF)

http://gcc.gnu.org/

Antaris/RazorEngine – GitHub

https://github.com/Antaris/RazorEngine

RazorEngine がすごく便利 (System.Web.Razor のラッパーライブラリ , テンプレートエンジン , Razor 記法 ) - いろいろ備忘録日記http://d.hatena.ne.jp/gsf_zero1/20121030/p1

Organize Includes Comes to CDT

http://www.eclipse.org/community/eclipse_newsletter/2013/october/article3.php

Page 37: Power shell で DSL

ご清聴ありがとうございました!


Recommended