我了解如何實作(驗證)setter ( def item=),但如何攔截<<對欄位的操作?
class Bla
attr_reader :item
def initialize
@item = []
end
# only called for =, =, -= operations (not <<)
def item=(value)
puts "Changing value to #{value}"
# pretend that there is a conditional here
@item = value
end
# This is wrong:
#def item<<(value)
# puts "adding value #{value}"
# @item << value
#end
end
b = Bla.new
b.item = ['one'] # works
b.item = ['one'] # works
b.item << 'two' # bypasses my setter
我試過了def item<<(value),好像不行。
uj5u.com熱心網友回復:
當您呼叫 時b.item << 'two',您是直接呼叫<<方法 on item。所以你在這里有幾個選擇:
<<直接在您的Bla類上實作,然后使用b << 'two':# in class Bla def <<(value) # do validation here @item << value end使用其他一些更好命名的包裝方法名稱,例如
add_item:# in class Bla def add_item(value) # do validation here @item << value end使用
@item具有自定義定義的特殊陣列類<<:class MyArray < Array def <<(item) # run validation here super end end # in Bla class def initialize @item = MyArray.new end
我可能會選擇選項 2,它是最簡單易讀的。
uj5u.com熱心網友回復:
這是一個替代建議:
class Bla
# DO NOT DEFINE A READER:
# attr_reader :item
def initialize
@items = []
end
def set_items(new_items)
puts "Changing value to #{new_items}"
# pretend that there is a conditional here
@items = new_items
end
def remove_item(item)
# pretend that there is a conditional here
@items -= items
end
def add_item(item)
# pretend that there is a conditional here
@items = items
end
end
通過不@items直接公開物件,您可以完全控制界面以了解如何操作變數。
(除非呼叫者做了一些非常hacky的事情,比如bla.instance_variable_get('@items')!!)
uj5u.com熱心網友回復:
class Pit
def <<(dirt)
puts 'shovel ' dirt
end
end
Pit.new << 'sandy loam'
# => shovel sandy loam
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/330622.html
上一篇:如何通過created_at[ruby]分組為2周增量
下一篇:是否可以保持非字母符號完好無損?
