From 9f2a330a6ce74e240b0fc290d1b70f0bad9c658b Mon Sep 17 00:00:00 2001 From: Holger Just Date: Sat, 15 Jul 2017 11:13:41 +0200 Subject: [PATCH] Support arbitrarily nested Procs when setting/merging fields --- lib/rackstash/fields/abstract_collection.rb | 4 +++- lib/rackstash/fields/tags.rb | 2 ++ .../fields/abstract_collection_spec.rb | 21 ++++++++++++++----- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/rackstash/fields/abstract_collection.rb b/lib/rackstash/fields/abstract_collection.rb index 0791005..d616713 100644 --- a/lib/rackstash/fields/abstract_collection.rb +++ b/lib/rackstash/fields/abstract_collection.rb @@ -104,6 +104,8 @@ module Rackstash def resolve_value(value, scope: nil) return value unless value.is_a?(Proc) scope == nil ? value.call : scope.instance_exec(&value) + rescue + value.inspect end # 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 return utf8_encode(exception) when ::Proc - return utf8_encode(value.inspect) + return normalize(value, scope: scope, wrap: wrap) when ::BigDecimal # A BigDecimal would be naturally represented as a JSON number. Most # libraries, however, parse non-integer JSON numbers directly as diff --git a/lib/rackstash/fields/tags.rb b/lib/rackstash/fields/tags.rb index 8eb4c26..bd476e6 100644 --- a/lib/rackstash/fields/tags.rb +++ b/lib/rackstash/fields/tags.rb @@ -67,6 +67,8 @@ module Rackstash value = value.map { |tag| normalize_tags(tag, scope: scope) } value.flatten! value + elsif value.is_a?(Proc) + normalize_tags(value, scope: scope) elsif value.respond_to?(:to_ary) value = value.to_ary.map { |tag| normalize_tags(tag, scope: scope) } value.flatten! diff --git a/spec/rackstash/fields/abstract_collection_spec.rb b/spec/rackstash/fields/abstract_collection_spec.rb index 5ce1d04..1606202 100644 --- a/spec/rackstash/fields/abstract_collection_spec.rb +++ b/spec/rackstash/fields/abstract_collection_spec.rb @@ -489,18 +489,29 @@ describe Rackstash::Fields::AbstractCollection do describe 'with Proc' 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).encoding).to eql Encoding::UTF_8 expect(normalize(proc)).to be_frozen end - it 'inspects a nested proc' do - inner = proc { :return } - outer = proc { inner } + it 'calls a nested proc and normalizes the result' do + inner = -> { :return } + outer = -> { inner } - expect(normalize(outer)).to match %r{\A#\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