AutoOpenAttributeについて
F# Advent Calendar 2014 - connpassの2日目です。
今回は、AutoOpenを紹介します。
AutoOpenとは、モジュールを自動でopenする仕組みです。主に言語やフレームワークでよく使うモジュールを提供するときに使います。主にライブラリ開発者に対する機能で、利用者は使うことは無いと思います。 実際に使うときは、AutoOpenAttributeを使用します。
しかし、あまりにも開くモジュールが多すぎると利用者はビックリしてしまうので、ほどほどにしましょう。
MSDNを見ても何の事か分からないので、F#の言語仕様書を見てみましょう。「Special Attributes and Types」という章にAutoOpenAttributeの記述があります。
When applied to an assembly and given a string argument, causes the namespace or module to be opened automatically when the assembly is referenced. When applied to a module without a string argument, causes the module to be opened automatically when the enclosing namespace or module is opened.
「アセンブリと、モジュールに対してAutoOpenAttributeを適用できる」と書いてあります。それぞれの使い方を説明します。
モジュールに適用する場合
よく使うパターンです。モジュールに対してAutoOpenをつけると、親のモジュール、名前空間がopenされた時に、自動でopenされます。
使い方はこんな感じ。
module A = let f x = x [<AutoOpen>] module B = let g x = x * 2 open A let x = g 1 (* Bモジュールの関数を使える *)
アセンブリに適用する場合
アセンブリにAutoOpenを付け、開きたいモジュール名を指定します。AutoOpenが付与されたアセンブリをプロジェクトの参照に追加しただけで、自動でopenされるようになります。
使い方はこんな感じ。例ではモジュール定義のすぐ下に書いてますが、実際に使うときはAssemblyInfo.fs
などに書くといいと思います。
module A = let f x = x module B = let g x = x * 2 [<assembly: AutoOpen("A.B")>] do ()
こちらの機能は、強力すぎるので使う機会が少ないと思いますし、使わないほうがいいと思います。
F# では、FSharp.Coreがこの方法を使っています。いつも使えるListモジュール等は、アセンブリに対するAutoOpenで提供されています。 ソースコードはこの辺りです。 特別扱いをするのではなく、言語の機能を使って提供しています。素晴らしいですね!
つまり、AutoOpenを外したFSharp.Coreを作れば、明示的にopenしないとListモジュールなどは使えないってことでしょうか? 既存のソースコードはコンパイルエラーになるはずです(試してないけど)。仕事場で隣の人が席を外している間に悪戯してやりましょう。