При написании повторяющегося кода с мутацией в рубине, я часто ловлю себя после этой схемы: (. x
часто не имеет такую же форму, как some_data
, поэтому простой map
не будет делать)Есть ли абстракция для шаблона declare-update-return?
def build_x some_data
x = [] # or x = {}
some_data.each do |data|
x.some_in_place_update! (... data ...)
end
x
end
Есть ли более идиоматический или лучший способ написать код, который следует за этим шаблоном?
[править] Реальный пример:
def to_hierarchy stuff
h = {}
stuff.each do |thing|
path = thing.uri.split("/").drop(4)
sub_h = h
path.each do |segment|
sub_h[segment] ||= {}
sub_h = sub_h[segment]
end
sub_h.merge!(
data: thing.data,
)
end
h
end
Это начинается с плоским списком thing
с, которые связаны, но отдельными uri
с. Он преобразует этот плоский список в иерархию, группируя связанные thing
s, которые имеют одинаковые segment
s из uri
. Это следует описанному мной шаблону: инициализировать h
, перебрать некоторые данные и мутировать h
по пути, а затем выплюнуть h
в конце.
[edit2] Другой связанный пример
def count_data obj
i = if obj[:data] then 1 else 0
obj.each do |k, v|
i += count_statements v unless :data == k
end
i
end
Непонятно, что вы хотите. 'x = []', за которым следует 'x.some_in_place_update! (data)' делает 'some_in_place_update!' метод 'Array', и его название подразумевает, что он модифицирует массив' x' на месте (если задан элемент 'some_data 'как входной), хотя он пуст. Вы действительно * исправили 'Array' новым методом? Это очень помогло бы узнать, что делает «some_in_place_update!». – Borodin
вы можете использовать один или два примера реальных методов с этим шаблоном? – tessi
@Borodin «на месте обновления», возможно, был плохим способом описания того, что я на самом деле имел в виду. Я пытался передать идею о том, что объект 'x' был мутирован этим вызовом метода. –