tcrayford/Values

A recursive version of `to_h`

blinsay opened this issue · 5 comments

I've been using a toooooooon of nested Value types lately. They rule. The only downside is writing a bunch of custom to_h methods so I can serialize them to JSON.

Address = Value.new(:street, :zip)
Value.new(:name, :address)
User.with(name: 'blinsay', address: Address.with(street: 'the internet', zip: '12345')).to_h
# => {:name=>"blinsay", :address=>#<Address street="the internet", zip="12345">}

I've been working around this by doing something like the following, but it sucks to have to do this in every new project:

module RecursiveToHash
  def to_h
    pairs = to_a.map do |k, v|
      if v.respond_to?(:to_h)
        [k, v.to_h]
      else
        [k, v]
      end
    end

    pairs.to_h
  end
end

class Value
  def self.create(*fields, &block)
    new(*fields, &block).tap do |klass|
      klass.prepend(RecursiveToHash)
    end
  end
end

Thoughts on making to_h recursive by default, or adding a to_h_recursive method?

Making to_h recursive seems to make sense to me. Are there any real downsides of doing that? Obviously there's some potential perf impacts, but I can't think of many other issues. Wanna send a PR?

I'll whip something up tomorrow.

Since a Value is immutable you can't have a loop, right?

On Thursday, August 27, 2015, Ben Linsay notifications@github.com wrote:

I'll whip something up tomorrow.


Reply to this email directly or view it on GitHub
#43 (comment).

Since a Value is immutable you can't have a loop, right?

Sounds right to me.

Opened up a PR

@tcrayford since you merged #44, this should be closed?