Sha256: b0d0180bd2735f76d83a09e034fc98566cc75ca357929642c2972951128b9e32
Contents?: true
Size: 1.65 KB
Versions: 37
Compression:
Stored size: 1.65 KB
Contents
# frozen_string_literal: true class ReeObject::ToHash include Ree::FnDSL fn :to_hash do def_error { RecursiveObjectErr } end BASIC_TYPES = [ Date, Time, Numeric, String, FalseClass, TrueClass, NilClass, Symbol, Module, Class ].freeze contract( Any => Or[Hash, ArrayOf[Any], *BASIC_TYPES] ).throws(RecursiveObjectErr) def call(obj) recursively_convert(obj, {}, {}) end private def recursively_convert(obj, acc, cache) ancestors = obj.class.ancestors if ancestors.intersection(BASIC_TYPES).size > 0 obj elsif obj.is_a?(Array) convert_array(obj, acc, cache) elsif obj.is_a?(Hash) convert_hash(obj, acc, cache) elsif obj.respond_to?(:to_h) convert_hash(obj.to_h, acc, cache) else convert_object(obj, acc, cache) end end def convert_array(obj, acc, cache) obj.map { |el| recursively_convert(el, {}, cache) } end def convert_hash(obj, acc, cache) obj.each do |k, v| key_sym = k.to_sym acc[key_sym] = recursively_convert(v, {}, cache) end acc end def convert_object(obj, acc, cache) return obj if obj.is_a?(Class) || obj.is_a?(Module) if cache.key?(obj.object_id) raise RecursiveObjectErr, "Recursive object found: #{obj}" end cache[obj.object_id] = true obj.instance_variables.each do |var| key_name = var.to_s.delete("@") key_sym = key_name.to_sym key = key_sym value = obj.instance_variable_get(var) acc[key] = recursively_convert(value, {}, cache) end cache.delete(obj.object_id) acc end end
Version data entries
37 entries across 37 versions & 1 rubygems