method_missing()とsend()でフック(処理を捕捉)

はてなブックマークに追加はてなブックマーク Yahoo!ブックマークに登録 ニフティクリップに追加 Livedoor クリップに追加 BuzzurlにブックマークBuzzurlにブックマーク Twitterに投稿  

=追記(2010/07/23)
Rubyベストプラクティスのひとり読書。理解が難しかった部分を中心にまとめています。
書籍から引用しすぎと思われたページ、理解したページなどを削除して、当初より公開ページを減らしました。すいません。
読書のまとめ記事は難しいと感じたので、今後はブログで読書のまとめは書かないでおきます。差し障りがあれば現存するページも削除致しますので予めご了承下さい。
=追記ここまで


p73あたりのコードを参考に、少々修正を加えて試してみる。
Rubyのmethod_missing()は面白い機能です。
簡単に説明すると、未定義の存在しない名前のメソッドが実行された場合に、method_missing()によりフック(処理を捕捉)することができます。
そして、method_missing()をオーバーライドすることにより、カスタマイズができる。


Prawnでmethod_missing()とsend()を試す

まずは、Prawnライブラリをインストール。

gem install prawn 

コード。

require "rubygems"
require "prawn"
 
class Prawn::Document
  def self.generate(file, *args, &block)
    pdf = Prawn::Document.new(*args)
    pdf.instance_eval(&block)
    pdf.render_file(file)
  end
end
 
file = "shapes.pdf"
 
=begin
# これでも動くがもう少しすっきりさせたい
Prawn::Document.generate(file) do
  fill_color "ff0000"
 
  # 赤で塗りつぶした円
  circle_at [100, 100], :radius => 25
  fill
 
  # 黒い線の透明な円と、その円の中心から伸びた直線を描く
  circle_at [300, 300], :radius => 50
  line [300, 300], [350, 300]
  stroke
 
  # 黒い線の赤で塗りつぶした六角形
  polygon [100, 250], [200, 300], [300, 250],
          [300, 150], [200, 100], [100, 150]
  fill_and_stroke
end
=end
 
# fill_circle_atなど存在しない名前のメソッドが実行された場合、method_missingにくる
# fill_some_method, stroke_some_method, fill_and_stroke_some_method など未定義のメソッドを処理する
def method_missing(name, *args, &block)
  case name.to_s
  when /^my_fill_and_stroke_(.*)/
    send($1, *args, &block); fill_and_stroke
  when /^my_stroke_(.*)/
    send($1, *args, &block); stroke
  when /^my_fill_(.*)/
    send($1, *args, &block); fill
  else
    super
  end
end
 
# カスタムしたmethod_missing中のsendにより、定義されていないメソッドが実行される
Prawn::Document.generate(file) do
  fill_color "ff0000"
 
  my_fill_circle_at [100, 100], :radius => 25
 
  my_stroke_circle_at [300, 300], :radius => 50
  my_stroke_line [300, 300], [350, 300]
 
  my_fill_and_stroke_polygon [100, 250], [200, 300], [300, 250],
                          [300, 150], [200, 100], [100, 150]
end


実行結果

>ruby 73.rb

と実行すれば、同一ディレクトリに、shapes.pdf に円や六角形が描かれてファイルが作成されるはずです。
面白いですね、Module#method_missing(), Object#send。
あと、Prawnライブラリを使うと、驚くほど簡単にPDFファイルを生成できます。こちらもびっくり。


ここまでのまとめ

instance_eval
Proc#arity
method_missing()とsend()
alias_method

instance_evalに基づいたインターフェスの場合、alias_methodで対処。
p77のまとめあたりに書いてあるが難しいので復習する。


日時: 2010年06月24日 19:43
コメントを投稿






トラックバック

■この記事のトラックバックURL:
http://www.mapee.jp/mpe334/mt-tb.cgi/533

この記事にトラックバックされる方は、参照先が分かるようにするために、「method_missing()とsend()でフック(処理を捕捉)」へのリンクをお願いいたします。
以下のHTMLタグをトラックバック送信元ページ内に挿入して下さい。



※この記事へのリンクがない、また関連のないページからのトラックバックは反映されませんので、ご了承下さい。






あわせて読みたいブログパーツ
フィードメーター - Ruby勉強ルーム