※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。



Hello Functor: pattern based method dispatch in ruby
June 18, 2008
ruby 界隈で一歩先へいく革新的なイニシアティブのひとつがWavesプロジェクトです。 これはrubyベースのウェブアプリケーションでオープンソースフレームワークです。 これは皆が「次世代」だと思うはずです。 これは美しく簡潔なコードで書かれています。 Lambdas はwavesでは非常にはっきりしています。 リソースの実装が マッピングを基礎付けました。 MVC パラダイム (せいぜい必要な)を調べ始める前にResources は一級市民です(?)

このプロジェクトからデザインと実装の美しい2つの小さなgemが生まれました。 1つは Autocodeで
、クラスとモジュールを自動的に読み込みんだり生成したりするライブラリです。
Autocode に関する詳しい情報がここ(http://dev.zeraweb.com/introducing-autocode-0-9-9/)にあります。

もうひとつは、私にとってより魅力的なもので Functor と呼ばれるシンプルで小さなgemです。それはここで詳しく説明します。これは Topher Cyll 氏が最近開発した multi gem の成果を元に作られています。

Waves プロジェクトからは独立した Functor の使用例。:

 functor( :normalize, Symbol, Hash ) { | name, options | options.merge!( :name => name ) }
 functor( :normalize, String, Hash ) { | p, options | options.merge!( :pattern => p ) }
 functor( :normalize, Regexp, Hash ) { | re, options | options.merge!( :pattern => re ) }
 functor( :normalize, Exception ) { | exception | { :exception => exception } }
 functor( :normalize, Hash ) { | options | options }

これはこうやって呼ばれます。:

 def map( *args, &block )  options = normalize( *args )  ...end

このコードは Functor 無しでどのようになるか考えてみてください。多分1ダースの入れ子の if-then-else や case-when などの構文になるでしょう。

さて、Functor はメソッドを多重定義するように振舞うように見えます。 java や C++ のような言語にはネイティブで存在しています。 Matz は「直交した特徴 [...] は複雑で爆発できる」(?)ため、ruby にメソッドの多重定義を実装するのを拒んでいます。 私は彼が正しいと思います。 Functor は直交性をこっそり許します。でもスタッフと一緒に船から落ちないでください。 あなたは正しいのですから。(?)

Functor の美しさはメソッドの多重定義以上のことを許容します。メソッドの多重定義することはクラスの引数の議論です。対照的に Functor は引数の引き当てにまず === 演算子を試し、それから == 演算子、そしてそれでもマッチしなかったら、あなたが提供している lambda や Proc(または何もあたらなければ :call が返されます) を試します。 このためこんなことが可能になるでしょう。:

 functor( :get, /^foo$/ ) { |p| "foo!" }
 functor( :get, /^bar$/ ) { |p| "bar!" }

get("bar") を呼ぶと bar! が返ります

あなたはfunctorをgemでインストールして弄れます (source is http://gems.github.com/):

 sudo gem install -r functor

または ソースコードは github で手に入れることができます。