From e13efe5ed3cef5fba403cd73f9f902c6cc654b4e Mon Sep 17 00:00:00 2001 From: Holger Just Date: Fri, 17 Feb 2017 19:10:27 +0100 Subject: [PATCH] Add consistent hash method to Rackstash::Fields::AbstractCollection This follows the rule that two objects which are eql? also have the same hash value. It is also required to ensure that we can use collections in sets, hashes and arrays where the hash-equality is checked for certain operations. --- lib/rackstash/fields/abstract_collection.rb | 10 ++++++++++ spec/rackstash/fields/abstract_collection_spec.rb | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/lib/rackstash/fields/abstract_collection.rb b/lib/rackstash/fields/abstract_collection.rb index d10120e..3f16bdf 100644 --- a/lib/rackstash/fields/abstract_collection.rb +++ b/lib/rackstash/fields/abstract_collection.rb @@ -22,6 +22,16 @@ module Rackstash end alias eql? == + # Compute a hash-code for this collection. + # + # Two collections with the same raw content will have the same hash code + # (and will compare using {#eql?}). + # + # @return [Integer] the hash ID of `self` + def hash + [self.class, raw].hash + end + # Show a human-readable representation of `self`. To get a machine- # readable "export" of the contained data, use {#as_json} or one of its # aliases instead. diff --git a/spec/rackstash/fields/abstract_collection_spec.rb b/spec/rackstash/fields/abstract_collection_spec.rb index d350e65..b62060f 100644 --- a/spec/rackstash/fields/abstract_collection_spec.rb +++ b/spec/rackstash/fields/abstract_collection_spec.rb @@ -91,6 +91,18 @@ describe Rackstash::Fields::AbstractCollection do end end + describe '#hash' do + it 'returns the same hash for the same raw content' do + collection.send(:raw=, [123, 'foo']) + + collection2 = Rackstash::Fields::AbstractCollection.new + collection2.send(:raw=, [123, 'foo']) + + expect(collection.send(:raw)).not_to equal collection2.send(:raw) + expect(collection.hash).to eql collection2.hash + end + end + describe '#raw' do it 'is a protected accessor' do expect { collection.raw = nil }.to raise_error NoMethodError