你不能直接默認這樣做,但是你可以使用Ruby的method_missing
構建類似的東西。
兩個解決方案:
解決方案1 - 使用包裝類
我們將調用這個類MArray
多分配陣列。
class MArray
def initialize(inner_array)
@inner = inner_array
end
def method_missing(meth, value)
# Check if assignement, and if it is then run mass-assign
if meth.to_s =~ /^\w+=$/
@inner.each { |itm| itm.send(meth, value) }
else
raise ArgumentError, "MArray: not an assignment"
end
end
end
我們還需要在Array
添加支持MArray
,使包裝就會發生。我們將調用該方法mas
爲 「大規模分配」:
class Array
def mas
# Wrap MArray around self
MArray.new(self)
end
end
用法很簡單:
Blob = Struct.new(:dab)
arr = [Blob.new] * 3
arr.mas.dab = 123
arr
=> [#<struct Blob dab=123>, #<struct Blob dab=123>, #<struct Blob dab=123>]
解決方案2 - 直接創建大規模分配支持納入Array
這由於我們直接修改Array
中的method_missing
,所以更加「危險」。它可能會產生一些奇怪的副作用(例如,如果method_missing
已被某個其他庫重新定義,或者您不小心在您不想要的情況下調用集體分配)。
它的工作原理是試圖檢測與複數的單詞(與s
結尾),然後觸發大規模分配任務:然後
class Array
def method_missing(meth, *args, &block)
# Check for plural assignment, and as an added safety check also
# see if all elements in the array support the assignment:
if meth.to_s =~ /^(\w+)s=$/ &&
self.all? { |itm| itm.respond_to?("#{$1}=") }
self.each { |itm| itm.send("#{$1}=", *args) }
else
super
end
end
end
使用率變得比MArray
更短:
Blob = Struct.new(:dab)
arr = [Blob.new] * 3
arr.dabs = 123
arr
=> [#<struct Blob dab=123>, #<struct Blob dab=123>, #<struct Blob dab=123>]
我的第一次嘗試是向數組類添加一個'dab = value'方法,並在最後將這些代碼添加到A類的文件中。正在聰明/愚蠢的檢查dab =是否只處理A類的實例:) –