1
0
mirror of https://github.com/meineerde/rackstash.git synced 2025-12-20 15:21:12 +00:00

Support arbitrarily nested Procs when setting/merging fields

This commit is contained in:
Holger Just 2017-07-15 11:13:41 +02:00
parent dd7f79db0a
commit 9f2a330a6c
3 changed files with 21 additions and 6 deletions

View File

@ -104,6 +104,8 @@ module Rackstash
def resolve_value(value, scope: nil) def resolve_value(value, scope: nil)
return value unless value.is_a?(Proc) return value unless value.is_a?(Proc)
scope == nil ? value.call : scope.instance_exec(&value) scope == nil ? value.call : scope.instance_exec(&value)
rescue
value.inspect
end end
# Note: You should never mutate an array or hash returned by normalize # Note: You should never mutate an array or hash returned by normalize
@ -157,7 +159,7 @@ module Rackstash
exception << "\n" << value.backtrace.join("\n") if value.backtrace exception << "\n" << value.backtrace.join("\n") if value.backtrace
return utf8_encode(exception) return utf8_encode(exception)
when ::Proc when ::Proc
return utf8_encode(value.inspect) return normalize(value, scope: scope, wrap: wrap)
when ::BigDecimal when ::BigDecimal
# A BigDecimal would be naturally represented as a JSON number. Most # A BigDecimal would be naturally represented as a JSON number. Most
# libraries, however, parse non-integer JSON numbers directly as # libraries, however, parse non-integer JSON numbers directly as

View File

@ -67,6 +67,8 @@ module Rackstash
value = value.map { |tag| normalize_tags(tag, scope: scope) } value = value.map { |tag| normalize_tags(tag, scope: scope) }
value.flatten! value.flatten!
value value
elsif value.is_a?(Proc)
normalize_tags(value, scope: scope)
elsif value.respond_to?(:to_ary) elsif value.respond_to?(:to_ary)
value = value.to_ary.map { |tag| normalize_tags(tag, scope: scope) } value = value.to_ary.map { |tag| normalize_tags(tag, scope: scope) }
value.flatten! value.flatten!

View File

@ -489,18 +489,29 @@ describe Rackstash::Fields::AbstractCollection do
describe 'with Proc' do describe 'with Proc' do
it 'calls the proc by default and normalizes the result' do it 'calls the proc by default and normalizes the result' do
proc = proc { :return } proc = -> { :return }
expect(normalize(proc)).to eql 'return' expect(normalize(proc)).to eql 'return'
expect(normalize(proc).encoding).to eql Encoding::UTF_8 expect(normalize(proc).encoding).to eql Encoding::UTF_8
expect(normalize(proc)).to be_frozen expect(normalize(proc)).to be_frozen
end end
it 'inspects a nested proc' do it 'calls a nested proc and normalizes the result' do
inner = proc { :return } inner = -> { :return }
outer = proc { inner } outer = -> { inner }
expect(normalize(outer)).to match %r{\A#<Proc:0x[0-9a-f]+@#{__FILE__}:#{__LINE__ - 3}>\z} expect(normalize(outer)).to eql 'return'
end
it 'returns the inspected proc on errors' do
error = -> { raise 'Oh, no!' }
expected_arguments = ->(arg1, args, arg3) { 'cherio' }
ok = -> { :ok }
outer = -> { [ok, error, expected_arguments] }
expect(normalize(outer))
.to be_a(Rackstash::Fields::Array)
.and contain_exactly('ok', error.inspect, expected_arguments.inspect)
end end
end end