Tuesday, January 24, 2012

Ruby to JSON Kata

I spent a large portion of my day today practicing for the Kata that I will be presenting on Friday. My original intention for this Kata was to take a well known kata that has a commonly accepted solution and rewrite it without using mutable data. Unfortunately, I was unable to find an existing kata that would showcase immutable data well. So, I decided to use the kata written by a fellow apprentice, Patrick Gombert, which does showcase immutable data rather well. Following is the Ruby implementation of this kata. Originally, this kata was written using Clojure, which really showcased immutable data. I believe that my implementation could be greatly improved by Clojure multimethods, which is what I would like to try tomorrow.

# Acceptace Criteria # ------------------ # nil -> null # Fixnum # Float # Booleans # Strings # Symbols -> converted to strings # Arrays -> all values converted to JSON # -> values can be anything # Hashes -> all values and keys converted to JSON # -> ignores keys that are not Symbols or Strings # -> values can be anything def str_or_sym?(data) data.is_a? String or data.is_a? Symbol end def convert(data) if data.nil? "null" elsif str_or_sym?(data) "\"#{data}\"" elsif data.is_a? Array "[#{data.map {|entry| convert(entry)}.join(", ")}]" elsif data.is_a? Hash "{#{data.map {|key, value| "#{convert(key)}: #{convert(value)}" if str_or_sym?(key)}.select {|x| !x.nil?}.join(", ")}}" else data.to_s end end describe "Ruby to JSON" do [ [nil, "null"], [1, "1"], [1.0, "1.0"], [true, "true"], [false, "false"], ["a", "\"a\""], [:a, "\"a\""], [[nil, :a], "[null, \"a\"]"], [{:a => nil, :b => :c}, "{\"a\": null, \"b\": \"c\"}"] ].each do |value, json| it "convert #{value.class}" do convert(value).should == json end it "array values can be #{value.class}" do convert([value]).should == "[#{json}]" end unless str_or_sym?(value) it "ignores hash key type #{value.class}" do convert({value => 1, :a => 1}).should == "{\"a\": 1}" end end it "hash values can be #{value.class}" do convert({:a => value}).should == "{\"a\": #{json}}" end end end

No comments:

Post a Comment