|
検索
タグ
ASP.NET
.NET
ASP.NET MVC
F#
Visual Studio
Azure
ASP.NET Core
ライトニングトーク
Plone
Selenium
AJAX
C#
jQuery
JavaScript
SQL Server
ADO.NET Entity Framework
WebMatrix
LINQ
EFCore
TypeScript
カテゴリ
最新の記事
最新のコメント
記事ランキング
最新のトラックバック
以前の記事
2026年 01月 2025年 12月 2025年 11月 2025年 10月 2025年 09月 2025年 08月 2025年 07月 2025年 06月 2025年 05月 2025年 04月 2025年 03月 2025年 02月 2024年 12月 2024年 11月 2024年 10月 2024年 09月 2024年 08月 2024年 04月 2024年 03月 2024年 02月 2024年 01月 2023年 12月 2023年 11月 2023年 10月 2023年 09月 2023年 08月 2023年 07月 2023年 06月 2023年 05月 2023年 04月 2023年 03月 2023年 02月 2023年 01月 2022年 12月 2022年 11月 2022年 10月 2022年 09月 2022年 08月 2022年 07月 2022年 06月 2022年 05月 2022年 04月 2022年 03月 2022年 02月 2022年 01月 2021年 12月 2021年 11月 2021年 10月 2021年 09月 2021年 08月 2021年 07月 2021年 06月 2021年 05月 2021年 04月 2021年 03月 2021年 02月 2021年 01月 2020年 12月 2020年 11月 2020年 10月 2020年 09月 2020年 08月 2020年 07月 2020年 06月 2020年 05月 2020年 04月 2020年 03月 2020年 02月 2020年 01月 2019年 12月 2019年 11月 2019年 10月 2019年 09月 2019年 08月 2019年 07月 2019年 06月 2019年 05月 2019年 04月 2019年 03月 2019年 02月 2019年 01月 2018年 12月 2018年 11月 2018年 10月 2018年 09月 2018年 08月 2018年 07月 2018年 06月 2018年 05月 2018年 04月 2018年 03月 2018年 02月 2018年 01月 2017年 12月 2017年 11月 2017年 10月 2017年 09月 2017年 08月 2017年 07月 2017年 06月 2017年 05月 2017年 04月 2017年 02月 2017年 01月 2016年 12月 2016年 11月 2016年 10月 2016年 09月 2016年 08月 2016年 07月 2016年 06月 2016年 05月 2016年 04月 2016年 03月 2016年 02月 2016年 01月 2015年 12月 2015年 11月 2015年 10月 2015年 09月 2015年 08月 2015年 07月 2015年 05月 2015年 04月 2015年 03月 2015年 02月 2015年 01月 2014年 12月 2014年 11月 2014年 10月 2014年 09月 2014年 08月 2014年 06月 2014年 04月 2014年 03月 2014年 02月 2014年 01月 2013年 12月 2013年 10月 2013年 09月 2013年 08月 2013年 07月 2013年 06月 2013年 05月 2013年 04月 2013年 03月 2013年 02月 2013年 01月 2012年 12月 2012年 11月 2012年 10月 2012年 09月 2012年 08月 2012年 07月 2012年 06月 2012年 05月 2012年 04月 2012年 03月 2012年 02月 2012年 01月 2011年 12月 2011年 11月 2011年 10月 2011年 09月 2011年 08月 2011年 07月 2011年 06月 2011年 05月 2011年 04月 2011年 03月 2011年 02月 2011年 01月 2010年 12月 2010年 11月 2010年 10月 2010年 09月 2010年 08月 2010年 07月 2010年 06月 2010年 05月 2010年 04月 2010年 03月 2010年 02月 2010年 01月 2009年 12月 2009年 10月 2009年 09月 2009年 07月 2009年 06月 2009年 05月 2009年 04月 2009年 03月 2009年 02月 2009年 01月 2008年 12月 2008年 11月 2008年 10月 2008年 09月 2008年 08月 2008年 07月 2008年 06月 2008年 05月 2008年 04月 2008年 03月 2008年 02月 2008年 01月 2007年 12月 2007年 11月 2007年 04月 2007年 03月 2007年 02月 2007年 01月 2006年 11月 2006年 10月 2006年 09月 2006年 08月 2006年 07月 |
2011年 01月 15日
前回の投稿で、IT プロがタスクの自動化に使うスクリプト言語として F# がいいよ! ということを書いた。
F# という言語そのものに対する評価のみならず、Visual Studio 2010 のコードエディタによる、インテリセンスやリアルタイムエラー表示といった、開発環境まわりも総合的に判断しての結論である。 では実際に実例を。 F#、というか、厳密には F# Script file (.fsx) を使い、ローカルマシンの Users グループに所属するユーザーを標準出力に一覧表示させてみることにする。 サンプルなのでこれだけだと実用的ではないが、これができれば Active Directory 上のロックアウトしたユーザーを抽出したり、新規ユーザーを追加したりとかも存分に行える。 要点は System.DirectoryServices.AccountManagement を使うこと。 詳細は下記が参考になる。 ![]() msdnマガジン 2008 January 「NET Framework 3.5 でディレクトリのセキュリティプリンシパルを管理する」 http://msdn.microsoft.com/ja-jp/magazine/cc135979.aspx F# Script file ( .fsx ) 一本で追加の参照設定を行うにはどうするかというと、fsi.exe 独自のディレクティブ、「#r "アセンブリ名"」を記述する。 #r "System.DirectoryServices.AccountManagement" 続けて、利用するクラスライブラリの名前空間をインポートしておいて、記述を短くできるようにしておく。 C# でいう using は、F# では open。 open System 次はディレクトリサービスに接続する。 今回はローカルマシンアカウントを扱うので、ContextType に Machine を指定する。 let context = new PrincipalContext(ContextType.Machine) 続けて、検索オブジェクトを使って、このコンテキストを元に Users ローカルグループを検索して取得する。 System.DirectoryServices.AccountManagement は "Query by Example" 方式で検索を行うのがポイント。 let example = new GroupPrincipal(context, "Users") Users ローカルグループが手に入ったら、Members プロパティを参照すれば、所属ユーザー一式が手に入る。 なお、FindOne() メソッドが返す型は、GroupPrincipal クラスの基底である Principal クラスとなっているので、GroupPrincipal 型へダウンキャストする ( C# では as などを使うところ、F# では :?> 演算子を使う )。 let members = (usersGroup :?> GroupPrincipal).Members あとは、こうして得られた Principal の集合から Name プロパティの集合へ射影し ( LINQ to Object の Select )、ソート。 最後に Name の集合を区切り文字を改行として単一文字列に連結 ( System.String の Join を使う ) して、コンソール出力することにする。 let userNames = members.Select(fun (u:Principal) -> u.Name).OrderBy(fun u -> u)C# のラムダ式は、F# では「fun 引数 -> 関数の本体」という形式で記述する。 LINQ の Select 拡張メソッドについては、オーバーロードバージョンの解決の兼ね合いで、ラムダ式の引数の型を ( 型推論に頼るのではなく ) 明示的に指定する必要があった。 以上で、題目のプログラムは完成である。 仕上げに処理完了のメッセージと、コンソールウィンドウが即座に閉じないよう、キー入力を待つことにしよう。 printfn "OK." 以上である。 いかがだろう。 F# としての構文や書き方についてはあんまり考慮することがなく、どちらかというと、System.DirectoryServices.AccountManagement の使い方がわかっているかどうかが焦点となってしまっている。 集合操作も F# 独自の機能を利用せず、普段 C# で使い慣れている LINQ を使ったのでなおさらだ。 これなら、普段は C# 使い・ VB 使いである人でも、容易に F# Script file を記述できるのではないだろうか。 むしろプログラミング言語の別は関係なくて、タスク達成のために .NET Framework のどのクラスを利用すればよいのかの知識こそが重要となってくる。 もうちょっと F# らしくしてみる以上で目的は達成されたのでじゅうぶんである。とはいえ、修練(?)の目的で、もうちょっと F# っぽく書き換えてみよう。 System.DirectoryServices.AccountManagement の使い方はこれ以上変えようがないが、Users ローカルグループのユーザーの集合 members を加工するところは F# の機能を使える。 まず、Principal の集合を Name プロパティ値への集合へ射影するのに Seq.map を使ってみる。 さらに LINQ のメソッドチェインと同様に、先に実行した関数の結果を、続く次の関数に渡すために、パイプライン演算子 ( |> ) を使ってみることにする。 members |> Seq.map (fun (u:Principal) -> u.Name)Seq.map 関数に、射影のラムダ式 fun (u:Principal) -> u.Name を渡して部分適用した関数、それにパイプライン演算子を使って members を引数に渡す ( 適用する ) わけだ。 続けて並べ替え。 (先のコード...) |> Seq.sort次に単一文字列への連結なのだが、どうにも、F# それ自体には .NET Framework の System.String.Join メソッドに相当する・代替できる機能を見つけることができなかった。 そこで、.NET Framework の System.String.Join メソッドを利用することにした。 しかし、String.Join メソッドは F# 上は引数の数はひとつ(タプルをひとつ受け取る)として扱われる。 すなわちこのままでは、パイプライン演算子で String.Join にうtなげていくことができない。 仕方がないので、String.Join をラップした関数 join を事前に定義しておく。 let join = fun (seq:seqこれで単一文字列への連結も、一連のパイプライン演算子による関数連鎖の中に組み込めるようになった。 そのままコンソール出力まで、パイプライン演算子でつなげていくことができる。 もういちどまとめると次のとおり。 members |> Seq.map (fun (y:Principal)->y.Name) |> Seq.sort |> join |> printfn "%s" これで LINQ を使わずとも F# の集合操作で実装できた。 パイプライン演算子は、Windows PowerShell のパイプ ( | ) とも似ていて、なかなか好きな演算子であるがいかがだろう。 さて以上のとおり、F# ( F# Script file、.fsx ) でもディレクトリサービスに対する操作を容易に記述できることがわかったと思う。 今回のサンプルの .fsx は、SkyDrive に Upload しておいたので、必要であればご参照頂きたい。 これをどう応用していこうか、いまからわくわくしているところだ。
by developer-adjust
| 2011-01-15 22:43
| .NET
|
ファン申請 |
||