block を後で評価 & method_missing の練習
- 作者: Paolo Perrotta,角征典
- 出版社/メーカー: KADOKAWA/アスキー・メディアワークス
- 発売日: 2010/08/28
- メディア: 大型本
- 購入: 18人 クリック: 533回
- この商品を含むブログ (125件) を見る
上の本を読みながら、研修向け Rubyイディオムをつくっているつもりが、自分のメタプログラミングの素振りになってたw。
describe "bockを 後で評価 & method_missing の例" do class Calc def initialize yield self if block_given? end def defun(key, &block) nodes[key.to_sym] = block end def exe(key, *args) nodes[key.to_sym].call(args) end def nodes @nodes ||= {} end def method_missing(m, *args, &block) exe(m.to_sym, *args) end end subject { Calc.new do |c| c.defun(:plus) {|args| args.reduce(:+) } c.defun(:minus) {|args| args.reduce(:-) } c.defun(:multi) {|args| args.reduce(:*) } c.defun(:greeting) {|name, world| "hello #{name}. I love #{world}" } end } it "処理の振り分けができること" do subject.exe(:plus, 4, 3, 2).should == 9 subject.exe(:minus, 10, 1, 2).should == 7 subject.exe(:multi, 2, 3).should == 6 subject.exe(:greeting, "haru01", "Ruby").should == "hello haru01. I love Ruby" end it "メソッド呼び出しのようにできること" do subject.plus(4, 3, 2).should == 9 subject.minus(10, 1, 2).should == 7 subject.multi(2, 3).should == 6 subject.greeting("haru01", "Ruby").should == "hello haru01. I love Ruby" end end
defun で ブロックは即評価せず、ハッシュに格納し、exeのところで評価している。
method_missing で exe を呼ぶことで 「subject.greeting("haru01", "Ruby")」 のように呼べるようにしてる。
その他、自己 Self
def initialize yield self if block_given? end .... Calc.new do |c| c.defun(:plus) {|args| args.reduce(:+) } c.defun(:minus) {|args| args.reduce(:-) } c.defun(:multi) {|args| args.reduce(:*) } c.defun(:greeting) {|name, world| "hello #{name}. I love #{world}" } end
nil ガード
@nodes ||= {}