mirror of
https://github.com/meineerde/rackstash.git
synced 2025-10-17 14:01:01 +00:00
Add Hash#set to set a field from a block if it doesn't exist yet
This allows to define default values for certain fields which can be inserted just before a Buffer is flushed. They won;t overwrite prior user-provided fields. Through the use of a block, expensive calculations for a field could be avoided if the field is not going to be inserted, e.g. because it exists already or is forbidden from being set.
This commit is contained in:
parent
ea77a8ae26
commit
031198cf14
@ -183,6 +183,33 @@ module Rackstash
|
||||
@forbidden_keys.include?(key)
|
||||
end
|
||||
|
||||
# Set a `key` of `self` to the returned value of the passed block.
|
||||
# If the key is forbidden from being set or already exists with a value
|
||||
# other than `nil`, the block will not be called and the value will not be
|
||||
# set.
|
||||
#
|
||||
# @param key [#to_s] the field name. When setting the field, this name
|
||||
# will be normalized as a frozen UTF-8 string.
|
||||
#
|
||||
# @yield [key] if the key doesn't exist yet, we call the block and use its
|
||||
# return value as the value to insert at `key`
|
||||
# @yieldparam key [String] The normalized key where the value is being
|
||||
# inserted
|
||||
# @yieldreturn [Object] the intended new value for `key` to be merged into
|
||||
# `self` at `key`.
|
||||
#
|
||||
# @return [Object, nil] The return value of the block or `nil` if no
|
||||
# insertion happened. Note that `nil` is also a valid value to insert
|
||||
# into the hash.
|
||||
def set(key)
|
||||
key = utf8_encode(key)
|
||||
|
||||
return if forbidden_key?(key)
|
||||
return unless @raw[key] == nil
|
||||
|
||||
@raw[key] = normalize(yield(key))
|
||||
end
|
||||
|
||||
# @return [::Array] a new array populated with the values from this hash.
|
||||
# @see #keys
|
||||
def values
|
||||
|
||||
@ -317,6 +317,39 @@ describe Rackstash::Fields::Hash do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#set' do
|
||||
it 'allows to set a normalized value' do
|
||||
expect(hash).to receive(:normalize).with(:value).and_call_original
|
||||
|
||||
hash.set(:symbol) { :value }
|
||||
|
||||
expect(hash['symbol']).to eql 'value'
|
||||
end
|
||||
|
||||
it 'ignores forbidden keys' do
|
||||
forbidden_keys << 'forbidden'
|
||||
|
||||
expect { |b| hash.set(:forbidden, &b) }.not_to yield_control
|
||||
expect { |b| hash.set('forbidden', &b) }.not_to yield_control
|
||||
|
||||
expect(hash['forbidden']).to be_nil
|
||||
end
|
||||
|
||||
it 'ignores existing keys' do
|
||||
hash['key'] = 'value'
|
||||
|
||||
expect { |b| hash.set(:key, &b) }.not_to yield_control
|
||||
expect { |b| hash.set('key', &b) }.not_to yield_control
|
||||
|
||||
expect(hash['key']).to eql 'value'
|
||||
end
|
||||
|
||||
it 'overwrites nil value' do
|
||||
hash['nil'] = nil
|
||||
expect { |b| hash.set('nil', &b) }.to yield_control
|
||||
end
|
||||
end
|
||||
|
||||
describe '#values' do
|
||||
it 'returns an array of values' do
|
||||
hash['string'] = 'beep'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user