Вот наивная попытка создать такой класс. Кажется, он отлично работает для «базового» использования:
class AppendOnlyHash < Hash
def []=(key, value)
raise "APPEND ONLY!!" if keys.include?(key)
super
end
end
Однако, это, безусловно, имеет некоторые недостатки.
Во-первых, что произойдет, если вы вызовете деструктивный метод для объекта, который пытается удалить некоторые ключи? Возможно, вы могли бы переопределить все такие методы - например, filter!
, keep_if
, delete
, compact!
, reject!
, select!
, transform_keys!
и transform_values!
. (Я что-нибудь пропустил? ...)
Тогда что делать с Hash#merge!
? Я думаю, что это может быть обработано специально тоже; поскольку допустимо использовать , если , никакие ключи не переопределяются.
И, наконец, как вы можете гарантировать, что значения хеша "только для добавления" никогда не будут мутированными ? Учтите следующее:
capitals = AppendOnlyHash.new
str = "paris"
capitals['france'] = str
str << " CHANGED"
Вы можете вызывать .freeze
для каждого значения, когда оно добавляется к хешу, но даже это не на 100% пуленепробиваемое - поскольку значение, в свою очередь, может быть другим Hash
, которое подвержено тому же поведению.
Итак, в общем, я думаю, что это возможно через мою базовую реализацию, описанную выше, но я бы с осторожностью относился ко все более сложным крайним случаям, вызванным нежелательной мутацией "странными способами".