メタプログラミングを使ってRubyにプロパティを追加する
Werner Schuster氏が、簡単な例を示しながら、Javaのようなプロパティをメタプログラミングを使ってRubyに追加する方法を示します。
- Ruby,
作者 Werner Schuster, 翻訳者 角谷 信太郎 - (株)永和システムマネジメント 投稿日 2008年3月4日 午前12時31分
Ruby 1.9での目玉機能といえばスレッド機構の変更やFiber(source)だが、これ以外にも標準ライブラリに加えられた便利な機能がある。Object#tap(source) については既に紹介した通りだ。tapメソッドはメソッドコールのチェインの途中に処理を割り込ませられる便利な機能だ。&演算子はProcオブジェクトをブロックへ変換し、ブロックをProcオブジェクトへ変換します。この場合、&はシンボル :+ をブロックへ変換しようとします。ブロックへの変換にはRuby組み込みの型変換が利用されます。ブロックへの型変換ではまず、Procオブジェクトが与えられているかをチェックします。ブロックが与えられていなければ、引数として与えられたオブジェクトをProcへと変換すべく to_procメソッドが呼び出されます。このとき、シンボル :+ に to_proc メソッドが定義されていれば、それが呼び出されます。Ruby 1.9では、Symbol#to_roc が定義されています。このto_procメソッドは、Procオブジェクトを返します。
つまり、&:+は{ |x, y| x + y }になるということです。
この振る舞いのおかげで次のようなコードを書けるようになる。
plus = :+.to_procSymbolクラスにto_procメソッドがあるということは、このやり方があらゆるシンボルに通用するということだ。
puts plus.call(1,2) # '3'が表示される
to_s = :to_s.to_proc
to_s.call(42) # 文字列"42"が返ってくる
to_procの実装はシンプルだ。Dave Thomas(PragDave)はその動作(source)をこう説明している。
def to_proc
proc { |obj, *args| obj.send(self, *args) }
end
to_procメソッドはProcを生成します。生成されたProcは、オブジェクトを引数にして呼び出されると、渡されたオブジェクトに対してsendメソッドを呼び出します。sendメソッドの第1引数のシンボルは、to_procのレシーバの自分自身です。ですから、たとえば names.map(&:upcase)の場合、namesに格納されている字列をイテレートするわけですが、その際にはnamesの各要素に対してupcaseメソッドを呼び出すブロックがコールバックされます。
(1..100).map(&:to_s)
は
(1..100).map{|x| x.to_s }
よりも短く書ける(この例では5文字短かい)。しかし、これは複雑さを増すに見合ったものだろうか? それともやりすぎだろうか?全然難しいことはなくて、メソッド名の由来は「カリー化(Currying)(source)」だ。カリー化とは、
proc {|x, y, z| x + y + z }.curry
は、次のようなprocを返すのと同じです
proc {|x| proc {|y| proc {|z| x + y + z } } }
カリー化(currying)とは、計算機科学分野の技法の一つ。複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること。
つまりカリー化とは、n個の引数を取るProcを1つの引数だけで呼ぶことができるということだ。この場合は(当たり前だが)処理の結果を返すことはできない――処理を実行するために必要な引数が与えられていないからだ。よって、処理結果の代わりに、(n -1)個の引数をとる新しいProcが返される。これが繰り返されて、Procのコードを処理するのに必要なだけの引数が揃ったら、Procは処理を実行してその結果を返す。
ruby-core メーリングリストの議論スレッドから利用例を紹介しよう。
plus_five = proc { |x,y,z| x + y + z }.curry.call(2).call(3)
plus_five[10] #=> 15
補足: plus_five は Procであり、[]演算子はProcではProcを実行するようにオーバーライドされている。
注意: Proc#curry が Ruby 1.9 に追加されたのはつい最近である。試してみるには、最新のsvnリビジョン(r15459以降)を利用しなければならない。
原文はこちらです:http://www.infoq.com/news/2008/02/to_proc-currying-ruby19
Werner Schuster氏が、簡単な例を示しながら、Javaのようなプロパティをメタプログラミングを使ってRubyに追加する方法を示します。
現在のRIAアーキテクチャにおいて、クライアント/サーバーの通信は重要な位置を占めています。本稿では、James WardとShashank TiwariがアドビによるオープンソースのBlazeDSメッセージングサーバーの世界へ飛び込みます。
ウィルス対策ソフトや情報漏えい防止用のソフトは、いわば影の存在です。ユーザの操作性やGUIを工夫する以上に、いかに目立たない存在となるかにその技術を注ぎ込んでいます。ここでは日立ソフトが開発した「秘文」の事例を紹介します。
Google Chartは、チャートを作成するためのWebサービスです。本稿では、Google Chartのインターフェースと、Rubyコードから簡単にチャートを生成することができるgchartrbライブラリの説明をします。
全二回からなるこの記事では、ダイナミックビジネスアプリケーション(Dynamic Business Applications:DBAs)の開発についての全体的な眺望を、アーキテクチャと方法論の観点から見ていくことになります。我々のゴールは、「ビジネスの変化や、その他に必要とされる変更に対して、いかにして容易に適応できるアプリケーションを構築していくか」を導きだすことです。
本稿では、Adrien Louis氏がESBベースのSOAに対する2つの接続形態についての賛否について説明しています。その2つとは、会社での単一のESB対「部門毎」に相互接続するESBによるシステムです。
誕生から2年を経てCometは「何が出来るのか」という議論から、「いかに実現するか」という議論に関心が移ってきたように見えます。そこで本稿では同じくJavaOneで数多く取り上げられたNetBeans 6.1とGlassFish v3を使いながら、サンプルを交えてCometを解説していく事にします。
この記事では、WSS3とMOSS 2007に難しい設定など一切せず、すぐに利用可能なWebサービスと、Javaと.NETからそのWebサービスを消費する方法に目を向けます。
No comments
返信