2007年 10月 15日

Class.new(DelegateClass(Object)).allocate が nil を返すように見える問題 (あるいは inspect の上書きは慎重に)

--- delegate.rb.orig	2007-10-15 03:54:11.000000000 +0900
+++ delegate.rb	2007-10-15 04:01:23.000000000 +0900
@@ -95,7 +95,7 @@
   klass = Class.new
   methods = superclass.public_instance_methods(true)
   methods -= ::Kernel.public_instance_methods(false)
-  methods |= ["to_s","to_a","inspect","==","=~","==="]
+  methods |= ["to_s","to_a","==","=~","==="]
   klass.module_eval {
     def initialize(obj)
       @_dc_obj = obj
@@ -137,6 +137,11 @@
       raise NameError, "invalid identifier %s" % method, caller(3)
     end
   end
+  klass.module_eval do
+    def inspect
+        "#<#{self.class}:#{"%#0x8d"%self.object_id}:DelegateClass->#{@_dc_obj.inspect}>"
+    end
+  end
   return klass
 end

実際にはちゃんとインスタンスが返ってた。でも inspect まで丸投げしてるのでそれがわからなかった。inspect をそのまま委譲するのは正しいとは思えない。inspect が信用できなくなる。

require "delegate"
p Class.new(DelegateClass(Object)).allocate
#=> before: nil
#=>  after: #<#<Class:0x1ef50>:0xe6b48d:DelegateClass->nil>

location_of... がエラーでるのはこれとはまた別の問題……ここまで気付くのに数時間かかった……