作者godfat (godfat 真常)
看板Ruby
标题Re: [问题] 删除new出来的instance(from class)
时间Sun Feb 11 20:30:29 2007
※ 引述《godfat (godfat 真常)》之铭言:
: 换一种概念的话,也可以用变数的变数来形容
: 试着做做看:
: class Qoo
: def cool
: puts 'cool ~~~~'
: end
: end
: qoo = Qoo.new
: x = Variable.new qoo
: y = x
: x.data # Qoo
: y.data # Qoo
: x.cool # 'cool ~~~~'
: y.cool # 'cool ~~~~'
: x.data = nil
: x.nil? # true
: y.nil? # true
简单地说,因为我们一次只能切断或接上一条链子(refer/point),
所以我们不能产生许多的链子,要集中一次处理。
用 Variable(上面的 x 与 y)去包装目标 instance(上面的 data),
接着所有要存取该 instance(data)的人,都透过这个 Variable(x, y)
也就是说,假设原本这样写:
x = Qoo.new
y = x
这样这个 Qoo 实体就是由 x, y 两条链子所链结
x = nil
打断一条,不影响另外一条
改写成
x = Variable.new(Qoo.new)
y = x
这样就是 x, y 两条链子指向 Variable, 再由他统一练链结到真正的目标
也就是说,我们只有一条链子指向真正的实体(由 x.data 或 y.data 实现)
当我们写
x.data = nil
时,y 跟 x 指向同样的实体,所以 y.data 同样也会是 nil
但是基於方便使用的缘故,每次都呼叫 x.data.nil? 实在太烦了
故将所有的 method 都直接转交由 x.data 去回应会比较简洁
如此一来,只要不随便使用 x = ??? 的话,x 的操作者甚至可以不用
在乎 Variable 这个中间层。
实作法很简单,强力建议看倌自己实作看看
不过如果还是一点概念都没有的话,这里点出两个提示
1. 需要 method_missing
这东西拿来做 wrapper 实在是太完美了
2. 需要重新定义所有原本已经存在的 method
不然你写 x.nil? 永远都会是 true, 因为 Variable 存在
需要把 x.nil? 改写成 x.data.nil?
以下有捏 XD
class Variable
instance_methods.each{|i|
# 改写所有的 instance method
next if i == '__id__' || i == '__send__'
# 不建议改写 __id__ 与 __send__, 所以跳过
module_eval <<-"end_eval"
def #{i} *arg, &block
method_missing :#{i}, *arg, &block
end
# 一律改写成这个 method 不见啦!
end_eval
}
def initialize data
@data = data
end
def method_missing msg, *arg, &block
@data.__send__ msg, *arg, &block
# 所有 message 一律转交给 @data 去回应
end
attr_accessor :data
# 唯一留下来的只有 initialize 和 data, data= 这三个 method.
end
--
生死去来、棚头傀儡、一线断时、落落磊磊
《花镜》-世阿弥
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.135.28.18