スポンサーサイト

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

F#入門初級編 第17回 Delegates と Events(5) IObservable

さて前回はEvent moduleの中のメソッドを紹介しました。今回はIObservableモジュール内のメソッドを紹介します。
 
一度例に戻ります。
 
type WhatTimeDidItHappenEventArgs (dateTime : System.DateTime) =
    inherit System.EventArgs()
    member this.DateTime = dateTime
 
type DelegateForPublisherExampWithDelg = 
                    delegate of obj * WhatTimeDidItHappenEventArgs -> unit
 
type PublisherExampWithDelg () =
    let _event1 = 
        new Event< DelegateForPublisherExampWithDelg,WhatTimeDidItHappenEventArgs>()
    member this.SomethingHappen() =
        _event1.Trigger(this,new WhatTimeDidItHappenEventArgs( System.DateTime.Now ))
    member this.Event1 = _event1.Publish
    
> let t = new PublisherExampWithDelg();;
val t : PublisherExampWithDelg
 > let originalEvent = t.Event1;;
val originalEvent :
  IEvent<DelegateForPublisherExampWithDelg,WhatTimeDidItHappenEventArgs> 
  
IEvent型というのは次のように定義されていました。
type IEvent<'Delegate,'Args when 'Delegate : delegate<'Args,unit> and 'Delegate :> System.Delegate> =
 interface
  inherit IObservable<'Args>
  inherit IDelegateEvent<'Delegate>
 end
 
ということで今回はObservable モジュールに準備されているIObservable<>型の値を引数にするメソッドを紹介します。
 
さて、イベントが点火されたとき、実行される手続きは前回はIDelegateEvent型であること(5行上を参照)を利用してAddHandlerを使って登録しましたが、今回はIObservable型であること(4行上を参照)を利用して関数を登録します。
 
Observableモジュールには次のようなaddメソッドがあります。
○Observable.add<'T>
 
// Signature:
Observable.add : ('T -> unit) -> IObservable<'T> -> unit
 
// Usage:
Observable.add callback source
 
よってこれを用いて手続きを登録してみます。
> Observable.add (fun (args : WhatTimeDidItHappenEventArgs) -> printfn "trigered at %A" (args.DateTime)) originalEvent;;
val it : unit = ()
 
トリガーを引いてみます。
> t.SomethingHappen();;
trigered at 2010/04/09 20:14:57
val it : unit = ()
 
こちらを使うとsenderオブジェクトは引数とできませんが、手軽に付加情報を引数とした関数を登録できます。
 
なお上は
originalEvent.Add (fun (args : WhatTimeDidItHappenEventArgs) -> printfn "trigered at %A" (args.DateTime)) と書くことができます。
 
 
それでは順番にObservableモジュールに準備されているメソッドを紹介していきたいと思います。
まずはObservable.filterとObservable.partitionです。前回Event.filterとEvent.partionを紹介しましたが、機能的にはほぼ同じなのですが、引数、返り値などの型が異なります。
 
Observable.filter : ('T -> bool) -> IObservable<'T> -> IObservable<'T>
Observable.partition : ('T -> bool) -> IObservable<'T> -> IObservable<'T> * IObservable<'T>
 
filterの方をつかってみます。
 
> let filteredEvent1 = 
    originalEvent 
     |> Observable.filter(fun (whatTimeArgs : WhatTimeDidItHappenEventArgs) ->
                        whatTimeArgs.DateTime.TimeOfDay.Seconds < 10) ;;
 
val filteredEvent1 : System.IObservable<WhatTimeDidItHappenEventArgs>
 
> filteredEvent1.Add(fun (args : WhatTimeDidItHappenEventArgs) ->printfn "%A event fired" args.DateTime);;
val it : unit = ()
 
> t.SomethingHappen();;
2010/04/10 16:59:02 event fired
val it : unit = ()
> t.SomethingHappen();;
val it : unit = ()
> t.SomethingHappen();;
2010/04/10 16:59:04 event fired
val it : unit = ()
次はpartitionの方です。
 
次にpartitionの方を使ってみます。
 
> let (lessThan10Event,notLessThan10Event) = //2つの窓口
    originalEvent 
     |> Observable.partition(fun (whatTimeArgs : WhatTimeDidItHappenEventArgs) ->
                        whatTimeArgs.DateTime.TimeOfDay.Seconds < 10) ;;
 
val notLessThan10Event : System.IObservable<WhatTimeDidItHappenEventArgs>
val lessThan10Event : System.IObservable<WhatTimeDidItHappenEventArgs>
 
> lessThan10Event.Add(fun  args ->printfn "秒は %A で10未満" args.DateTime);;
val it : unit = ()
> notLessThan10Event.Add(fun args -> printfn "秒は %A で10以上" args.DateTime);;
val it : unit = ()
 
Eventをfireしてみます。
 
> t.SomethingHappen();;
秒は 2010/04/10 17:04:59 で10以上
val it : unit = ()
> t.SomethingHappen();;
秒は 2010/04/10 17:05:01 で10未満
val it : unit = ()
 
さて、Observableモジュールのこれらの返り値はどれもIObservable<T'>型なので、|>を用いて繋げていくことができます。偶数秒でフィルターをかけて、その上で10秒未満と以上に分けた窓口を作ると次のようになります。
 
let (lessThan10AndEvenEvent,notLessThan10AndEvenEvent) = //2つの窓口
    originalEvent 
     |> Observable.filter(fun (whatTimeArgs : WhatTimeDidItHappenEventArgs) ->
                        whatTimeArgs.DateTime.TimeOfDay.Seconds % 2 = 0) 
 
     |> Observable.partition(fun (whatTimeArgs : WhatTimeDidItHappenEventArgs) ->
                        whatTimeArgs.DateTime.TimeOfDay.Seconds < 10) 
 
lessThan10AndEvenEvent.Add(fun  args ->printfn "秒は %A で10未満かつ偶数" args.DateTime)
notLessThan10AndEvenEvent.Add(fun args -> printfn "秒は %A で10以上かつ偶数" args.DateTime)
 
Eventをfireしてみます。
> t.SomethingHappen();;
秒は 2010/04/10 17:10:06 で10未満かつ偶数
val it : unit = ()
> t.SomethingHappen();;
val it : unit = ()
> t.SomethingHappen();;
秒は 2010/04/10 17:10:08 で10未満かつ偶数
val it : unit = ()
> t.SomethingHappen();;
秒は 2010/04/10 17:10:10 で10以上かつ偶数
val it : unit = ()
> t.SomethingHappen();;
val it : unit = ()
スポンサーサイト

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

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

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

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

この人とブロともになる

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