(hatena (diary ’Nobuhisa)) このページをアンテナに追加 RSSフィード Twitter

16/01/29 :

DIコンテナ使ってますか

海外のStack Overflowなどを見ていると、


"DI vs (Abstract) Factory Pattern"

"DI vs Service Locator Pattern"


という類の議論(質問)が多数見受けられる。

( 例えば: http://stackoverflow.com/questions/557742/dependency-injection-vs-factory-pattern )

回答の内容はごもっともである。(と思う)


結局のところ、DIコンテナ(ツール/ライブラリ)は使わずFactory等で解決している人が多いのかな。

かく言う自分も、どちらにすべきか度々迷っている・・・。

15/12/07 : 有為転変

[]F# Quiz : プロパティ

F# Advent Calender 2015の4日目の、ぐるぐるさんの記事を拝見していました。


僕はお仕事で F# + ASP.NET MVC の組み合わせを使うことが多いのですが、やはりC#/V○前提のフレームワークを用いる時はどうしてもクラスをモリモリ使うことになってしまいます。その辺が少しもどかしい。


さて、記事の中ではメンバーの定義についてはあまり触れられていませんでしたが、F#にはプロパティの実装方法が沢山あります。そして厄介なことに、アクセスした時の振る舞いなどが異なります。でも、手のかかる子ほど可愛い。(?)


そこで、ちょっとF#クイズを用意してみました。

以下の4つのプロパティ*1を評価した時に、それぞれどのような結果となるか考えてみてください。

まずは脳内のF# Interactiveで実行してみてね。


type Quiz() =
    let count =
        let counter = ref 0
        fun () -> incr counter ; !counter

    let lazyCount = lazy count ()


    member this.PropA = count ()

    member val PropB = count ()

    member this.PropC with get() = count ()

    member this.PropD with get() = lazyCount.Force()


答えはfsiが教えてくれます。(手抜き)

それぞれ複数回評価してみると違いが分かるかもしれません。

現場からは以上です。


おまけ

はてなユーザの皆さん、彩りの存在も思い出してあげてください。(白目

http://irodori.azurewebsites.net/

*1:PropDはおまけです

15/12/03 :

[]恐怖のおやすみエラー

F# Advent Calender 2015の2日目の記事を拝見していました。

同名の型などを定義することによって、既存の型の使用を制限する方法が紹介されていました。


ふと、

「そういえば、CompileMessage属性なんてものがあったなぁ」

と思い出したので、別パターンを書いてみました。

以下のようにすると、(1)XmlDocumentクラスがインテリセンスに表示されなくなり、(2)それでも自力でインスタンスを生成しようとするとコンパイルエラーが発生するようになります。*1


namespace System.Xml

module private AA =
    [<Literal>]
    let oyasumi = """
_____
| (^o^)ノ| < おやすみー
|\⌒⌒⌒ \
 \|⌒⌒⌒⌒|
    ̄ ̄ ̄ ̄ ̄
"""

// インテリセンスに表示させないための属性
[<CompilerMessage("隠蔽のための属性", 12345, IsHidden = true)>]
type XmlDocument =
    // コンストラクタにアクセスした時にエラーを発生させる
    [<CompilerMessage(AA.oyasumi, 12345, IsError = true)>]
    new() = {}


スクリーンショット

f:id:Nobuhisa:20151203062217p:image


おしまい。

*1:IsErrorプロパティをfalseにすることによって、エラーを警告にすることも可能

15/03/16 :

[][]Singletonパターンの「だらしない」実装

Singletonパターンに限らず、「初回アクセス時に初期化するプロパティ」などは比較的よく実装しますよね。

これを在り来りな方法で書けば、およそ以下のようになることと思います。

type Singleton private () =
    do printfn "生成されました"

    static let mutable instance = None

    static member Instance =
        match instance with
        | Some x -> x
        | None   -> let x = Singleton() in instance <- Some x ; x

> Singleton.Instance ;;
生成されました
val it : Singleton = FSI_0007+Singleton
> Singleton.Instance ;;
val it : Singleton = FSI_0007+Singleton

これで、実際にアクセスされるまでインスタンス化を遅らせることができました。


今行っていたことは正しく遅延評価です。

然すれば、lazyを使って以下のようにだらしなく書くこともできます。

type LazySingleton private () =
    do printfn "生成されました!"

    static let    instance = lazy LazySingleton()
    static member Instance = instance.Force()

> LazySingleton.Instance ;;
生成されました!
val it : LazySingleton = FSI_0007+LazySingleton
> LazySingleton.Instance ;;
val it : LazySingleton = FSI_0007+LazySingleton

結果はLazy<T>クラスの内部にキャッシュされているため、複数回評価をしてもインスタンスは無二のものとなります。シンプル!

15/02/11 : REFLECTION

[]誰得ボールZ

F#には、独自サフィックスを定義する機能がある。

今が旬の、誰にも使われない超マイナー機能。


例えば、以下のように定義すると「Z」というサフィックスが有効になる。

どこか懐かしい、胸がパチパチするようなサフィックス。

ちなみに、サフィックスとして使用できる文字は「Q, R, Z, I, N, G」のみです。

モジュールも関数も名前が重要だそうです。

module NumericLiteralZ =
    let FromZero () = "(´・_・`) バイバイ、天さん・・・"

    let FromOne () = "◯"

    let FromInt32 = function
        | n when (n >= 7) -> "いでよ神龍!🐲"
        | n -> String.replicate (max 1 n) "◯"

実行例:

> 1Z ;;
val it : string = "◯"
> 6Z ;;
val it : string = "◯◯◯◯◯◯"
> 7Z ;;
val it : string = "いでよ神龍!🐲"


ちょっと前に仕事でサフィックスの話が出ていたので、思い出したついでに書いてみました。


まとめ

使い道を教えて下さい。(衝撃