[ruby-list:39072] Re: 内包オブジェクトがnilになったら自分もnilになるには?

From: Yac <yac@...>
Date: 2004-01-24 08:06:50 UTC
List: ruby-list #39072
岡です。
>内包するオブジェクトが無効になった後のメソッド呼び出しは例外を
>発生させるようにします。
この件ですが、以下のように作ってみました。
最初、各メソッドに"raise RuntimeError unless @raw_object" を付けようかと思ったのですが、
メソッドの数が多くなってくると、ちょっと面倒です。
そこで、内包オブジェクトをnilにするメソッドが呼ばれた時点で自分が持っているメソッドで
例外が発生するようにしてしまえばいいかと思ったしだいです。そのため、undef_my_method()
で自クラスで定義したメソッドだけを例外を発生させる特異メソッドで置き換えてみました。

ただ、ちょっと自信がないので、アドバイスしてください。
・オブジェクトを指定して、メソッドを無効化する方法ってありますか?
・自クラスで定義したメソッドだけを抜き出すのは、以下のような方法でいいんですか?
  self.class.instance_methods(false)
・特異メソッドを定義するのに、evalを使っているんですが、他にいい方法はありませんか?
  (なんかちょっと大げさな気がして)
/OKA

class Class_Wrapper  
  def inspect
    self.class
  end
  
  private
  
  # ラップしてるクラス本来のメソッドはここで処理
  def method_missing(m_id, *params)
    missing_method_name = m_id.to_s
    if @raw_object == nil
      raise RuntimeError, "This object is no more worked.",caller
    end
    if methods.include?(m_id.to_s.downcase)
      send(m_id.to_s.downcase.intern, *params)
    else
      begin
        @raw_object.send(m_id, *params)
      rescue
        raise $!,$!.message, caller
      end
    end
  end
  
  def undef_my_method()
    instance_method_arr = self.class.instance_methods(false)
    eval_msg_arr = []
    instance_method_arr.each {|method_name|
      next if method_name == "inspect"
      eval_msg_arr.push "def self.#{method_name}(*params); raise RuntimeError, 'This object is no more worked.',caller; end"
    }
    eval eval_msg_arr.join("\n")
  end  
end

class MyHash < Class_Wrapper
  def initialize()
    @raw_object = {}
  end
  
  def add_key(key,val)
    @raw_object[key] = val
  end
  
  def show_val(key)
    @raw_object[key]
  end
  
  def remove
    @raw_object = nil
    undef_my_method()
  end
end


list = MyHash.new
list.add_key("A1","UJAUJA")
p list.show_val("A1")  # -> "UJAUJA"
list.remove
p list  # -> "MyHash"
list.show_val("A1")  # -> RuntimeError例外発生







In This Thread

Prev Next