前田です。

>これだと、いらなくなったメソッドがGCで回収されないので、
>ちょっと修正しました。

すみません、いらなくならないですね。

--
前田 修吾
----------
# once.rb

class Object
  ONCE_METHODS = {}

private
  def def_once(name, &body)
    if name.kind_of? Integer
      name = name.id2name
    end
    ONCE_METHODS[body.id] = body
    def_once_i(name, body.id)
  end
    
  def def_once_i(name, id)
    eval %{
      def #{name}
        def self.#{name}; @__#{name}__; end
        @__#{name}__ = ONCE_METHODS[#{id}].call
      end
    }
  end
end

class Module
private
  def def_once_i(name, id)
    module_eval %{
      def #{name}
        def self.#{name}; @__#{name}__; end
        @__#{name}__ = instance_eval(&ONCE_METHODS[#{id}])
      end
    }
  end
end