Today I Learned

One liner for recursively transforming to OpenStruct

hash = {
  name: "Bob",
  school: {
    name: "RSpec school",
    level: "secondary",
    region: {
      countryCode: "pl",
      region: "Bielsko"
    }
  }
}

JSON.parse(hash.to_json, object_class: OpenStruct)
=> #<OpenStruct name="Bob", school=#<OpenStruct name="RSpec school", level="secondary", region=#<OpenStruct countryCode="pl", region="Bielsko">>>

and here’s benchmark if you’re interested

require 'benchmark'
require 'json'

def build_nested_hash
  {
    name: 'Bob',
    school: {
      name: 'RSpec school',
      level: 'secondary',
      region: {
        countryCode: 'pl',
        region: 'Bielsko'
      }
    }
  }
end

n = 100_000

Benchmark.bm do |benchmark|
  benchmark.report('OpenStruct') do
    n.times do
      JSON.parse(build_nested_hash.to_json, object_class: OpenStruct)
    end
  end

  benchmark.report('Hash') do
    n.times do
      JSON.parse(build_nested_hash.to_json)
    end
  end
end
 $ ruby benchmark.rb
               user     system      total        real
OpenStruct  4.118626   0.010050   4.128676 (  4.129240)
Hash        0.986823   0.002627   0.989450 (  0.989538)

As you can see it’s quite slower than parsing to hash, but still rather acceptable

tested on ruby 2.6.5(M1)