Skip to content

Instantly share code, notes, and snippets.

@codekitchen
Created March 3, 2016 17:35
Show Gist options
  • Save codekitchen/071d57e418d8fb116fb5 to your computer and use it in GitHub Desktop.
Save codekitchen/071d57e418d8fb116fb5 to your computer and use it in GitHub Desktop.
require 'json'
module HashWithDupCheck
refine Hash do
def []=(k,v)
raise(ArgumentError, "key already exists: #{k.inspect}") if key?(k)
end
end
end
using HashWithDupCheck
puts JSON.parse(%[{"a": 5, "a": 6}])
@johana-star
Copy link

require 'json'

module HashWithDupCheck
  refine Hash do
    def []=(k,v)
      raise(ArgumentError, "key already exists: #{k.inspect}") if self.key?(k)

      super
    end
  end
end

using HashWithDupCheck

hash_with_dups = %[{"a": 5, "a": 6}]

puts JSON.parse(hash_with_dups)

class HashWithDupCheck2 < Hash
  def []=(k,v)
    if self.key?(k)
      raise ArgumentError, "key already exists: #{k.inspect}"
    else
      super
    end
  end
end

puts JSON.parse(hash_with_dups, :object_class => HashWithDupCheck2)

returns

{"a"=>6}
../refined_hash.rb:22:in `[]=': key already exists: "a" (ArgumentError)
    from /Users/smccutchen/.gem/ruby/2.2.2/gems/json-1.8.2/lib/json/common.rb:155:in `parse'
    from /Users/smccutchen/.gem/ruby/2.2.2/gems/json-1.8.2/lib/json/common.rb:155:in `parse'
    from ../refined_hash.rb:29:in `<main>'

Should raise an error on the first parse invocation.

@johana-star
Copy link

I've written this behavior out as a spec…

require 'json'
require 'rspec'

module HashWithDupCheck2
  refine Hash do
    def []=(k,v)
      raise(ArgumentError, "key already exists: #{k.inspect}") if self.key?(k)

      super
    end
  end
end

using HashWithDupCheck2

class HashWithDupCheck < Hash
  def []=(k,v)
    if self.key?(k)
      raise ArgumentError, "key already exists: #{k.inspect}"
    else
      super
    end
  end
end

describe "duplicate checking" do
  let(:hash_with_dups) { %[{"a": 5, "a": 6}] }

  context "Hash" do
    it "raises an error parsing JSON with duplicates" do
      expect { JSON.parse(hash_with_dups) }.to raise_error
    end
  end

  context "HashWithDupCheck" do
    it "raises an error parsing JSON with duplicates" do
      expect {
        JSON.parse(hash_with_dups, :object_class => HashWithDupCheck)
      }.to raise_error
    end
  end
end

I'll figure out how to fix this behavior, and then add a spec to hold it in place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment