Nullオブジェクト
30分プログラム、その158。Nullオブジェクトを作る。
RubyのNilClassは無関係で、デザインパターンのほうのNullオブジェクト。適当に要約すると、処理Aをするクラスと、処理Bをするクラスと、何もしないクラスを用意して、それぞれ状況に応じて別のクラスに渡すようにすると、処理をする場合と処理をしない場合をわける必要がなるなる、というパターン。
で、このNullオブジェクトを簡単につくるためのクラスを定義してみる。
最初は、いかなるメソッドが呼ばれてもエラーにならないクラスを定義してみた。でも、これだとメソッド名を間違えても文句を言わなくて困るので、指定したメソッドだけ処理するクラスも定義した。
使い方
irb> require 'nullobject' # eaterに何を食べさせても、エラーにならない irb> eater = Eater.new => #<Eater:0x10a12b0> irb> eater.f => nil irb> eater.b => nil irb> eater.g => nil # fとgだけを受けつけるFooを作成 irb> Foo = NullObject.new :f,:g => Foo irb> foo = Foo.new => #<Foo:0x108bbb8> irb> foo.f => nil irb> foo.g 1,2,3 => nil # fとg意外を食べさせると、エラーを吐く irb> foo.h NoMethodError: undefined method `h' for #<Foo:0x108bbb8> from (irb):11
ソースコード
#! /opt/local/bin/ruby -w # -*- mode:ruby; coding:utf-8 -*- # # nullobject.rb - # # Copyright(C) 2007 by mzp # Author: MIZUNO Hiroki <hiroki1124@gmail.com> # http://mzp.sakura.ne.jp/ # # Timestamp: 2007/10/17 23:13:09 # # This program is free software; you can redistribute it and/or # modify it under the same terms as Ruby itself. # class Eater def method_missing(*_); end end class NullObject def self.new(*methods) klass = Class.new klass.module_eval{ methods.each{|name| define_method(name){|*args| } } } klass end end if $0 == __FILE__ then NullFoo = NullObject.new :bar,:baz foo = NullFoo.new foo.bar foo.baz 1,2,3 end