Re: [問題] 刪除new出來的instance(from class)
※ 引述《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
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 4 之 4 篇):
Ruby 近期熱門文章
PTT數位生活區 即時熱門文章