スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#入門基本編落穂拾い その35 アクセス制御

以前ブログでクラス定義の話題がでましたが、discriminated unionも内部的にはクラスを用いて実装されていますし、その上さらにmoduleそのものもクラスを用いて実装されていますので、アクセス制御のできる場所がそこらここらにあります。
 

 
//let 束縛
let private myPrintf1() = printfn "*"
let mutable private  myVal = 0
 
//discriminated union
 
type internal MyUnion =
    | Num of int
    | Str of string
 
//module
 
module internal mySecretModule =
 
  let myPrintf2() = printfn "********"
 
たいてい識別子(こちら側が付けた名前)の前と覚えておけばよいかと思います。
 
さて、上を全部F#Interactiveに送ると次のように表示されます。
 
val private myPrintf1 : unit -> unit
val mutable private myVal : int = 0
type internal MyUnion =
  | Num of int
  | Str of string
module internal mySecretModule = begin
  val myPrintf2 : unit -> unit
end
 
これらを、送られた型や値等のシグネチャーといいます。(2行目の=0という値は余分ですが)
次にコンパイラを使ってシグネチャーが表記されるファイル(シグネチャーファイルといいます)を作ってみます。
 
ファイル名 myLib003.fs
 
module myLib0030
 
let myPrint1() = printfn "****"
let myPrint2() = printfn "********"
 
let mutable  myVal = 0
 
//discriminated union
 
type MyUnion =
    | Num of int
    | Str of string
 
 
次のようにコンパイルします。
C:\Users\T_GYOUTEN\FSharp\Proj001>fsc myLib003.fs --sig:myLib003.fsi --target:library
 
できたファイルmyLib003.fsiの中身は次のようになっています。
 
module myLib0030
val myPrint1 : unit -> unit
val myPrint2 : unit -> unit
val mutable myVal : int
type MyUnion =
  | Num of int
  | Str of string
 
なおシグネチャーファイルはソールファイルと同名で拡張子はfsiという名前にしておいた方が後々使いやすいです。
このファイルを作れてもあまり嬉しい気分はしませんが、実はこのファイルには別の利用方法があります。
実は、このファイルを使ってアクセス制御ができるのです。
どのようにするかといえば、例えば上のファイル内容から、例えば2,3行目を除いて次のようにします。
 
module myLib0030
val myPrint1 : unit -> unit
type MyUnion =
  | Num of int
  | Str of string
 
このファイルはマスク(抜き型)として使うことができ、コンパイルするときに、ソースファイルと一緒にこのシグネチャファイルを渡すと(シグネチャファイルの方を先に渡す)シグネチャファイルに残っている値や型だけが、外部から参照可能となります。
 
それでは、コンパイルしてみます。
C:\Users\T_GYOUTEN\FSharp\Proj001>fsc myLib003.fsi myLib003.fs --target:library
//シグネチャファイル ソースファイルの順になっていることに留意!
 
これで、外部から参照できる、値、型はmyPrint1とMyUnion型だけになります。
 
最後にVisual Studioでのシグネチャファイルの利用法を紹介します。
 
例として、プロジェクトForBlogLib2 というプロジェクト(ターゲットクラスライブラリ)を作り、
さらにその中にファイルmodule1.fsを作ります。
module myLib001
 
type myExType =
    |Num of int
    |NumNum of int*int
 
let myVal01 = 1
let myVal02 = 2
 
let myFunc01 = (fun x -> x + 1)
let myFUnc02 = (fun x -> x + 2)
 
次にSolution Explorerでプロジェクト名を右クリックし、add > new Itemとしてから、F# Signature Fileを選びます。このとき先ほどのファイルと同名のファイル名で、拡張子をfsiとした空のファイルを開きます。次にsolution Explorerで、このファイルをmodule1.fsの直前に移動します。
次にファイルの先頭にmyLib001を入力します。
module1.fsのmodule myLib001以降(この行は含まない)を、F# Interactiveに送ります。
すると、
 
type myExType =
  | Num of int
  | NumNum of int * int
val myVal01 : int = 1
val myVal02 : int = 2
val myFunc01 : int -> int
val myFUnc02 : int -> int
 
とシグネチャが表示されるので、これをmodule1.fsiの二行目以降にコピーします。
するとmodule1.fsiの内容な次のようになります。
type myExType =
  | Num of int
  | NumNum of int * int
val myVal01 : int = 1
val myVal02 : int = 2
val myFunc01 : int -> int
val myFUnc02 : int -> int
 
値は必要ないので、=1と=2は消します。
 
module myLib001
 
type myExType =
  | Num of int
  | NumNum of int * int
val myVal01 : int 
val myVal02 : int 
val myFunc01 : int -> int
val myFUnc02 : int -> int
 
さてこれで、準備が整ったので、アクセス制限を付けます。
privateにしたい場合は、その行を消去するか、関数や型の識別子の前にprivateと入力します。
internalも同様です。publicにしたいものは、そのままにしておきます。(デフォルトはpublicです。)
 
例えば次のようにしたとします。
module myLib001
 
type myExType =
  | Num of int
  | NumNum of int * int
//val myVal01 : int 
val myVal02 : int 
val internal myFunc01 : int -> int
val private myFUnc02 : int -> int
 
これをコンパイルしてdllファイルを作り、外部からmyLib001.で参照すると、型についての情報と、myVal02だけが、参照可能になります。
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。