上下文:我正在尝试在 Ruby 中建立一个装饰器模式。由于装饰器应该将所有未知方法委托给底层对象,因此我使用了 Delegator 类。我本可以使用 SimpleDelegator,但我想完全了解我在做什么。
所以我提出的基本代码是:
class Decorator < Delegator
def initialize(component)
super
@component = component
end
def __setobj__(o); @component = o end
def __getobj__; @component end
def send(s, *a); __send__(s, *a) end
end
这与 SimpleDelegator 的实现完全相同。看起来不错。
但我不想让处理装饰器的代码知道它正在操纵装饰器。我想要完全透明。
这一刻Decorator.new(Object.new).class
回来了Decorator
所以我修改了一下,想出了这个:
class Decorator < Delegator
undef_method :==
undef_method :class
undef_method :instance_of?
# Stores the decorated object
def initialize(component)
super
@component = component
end
def __setobj__(o); @component = o end
def __getobj__; @component end
def send(s, *a); __send__(s, *a) end
end
这样,我可以安全地使用class
或instance_of?
在我的 Decorated 对象上,它会通过 method_missing(由 Delegator 实现)将方法发送到底层对象。
问题是:我不明白为什么我必须 undef:class
和:instance_of?
. 我可以看到 BasicObject 定义了:==
所以我不得不取消定义它但是那两个呢?我查看了 BasicObject 文档和 C 代码中的一些内容,但没有找到任何东西。我查看了 Delegator 文档和代码,也没有找到任何东西。似乎 Delegator 包含 Kernel 模块,但是 Kernel#class 还是 Kernel#instance_of?不存在。
这两种方法是从哪里来的?如果它们根本没有实施,为什么我需要取消定义它们?我想我一定是遗漏了一些关于 Ruby 的对象模型之类的东西。
谢谢。