When you try calling stringify_values on a Ruby Hash
I needed to convert all values in a hash to strings. Seemed simple enough, but I went through several attempts before finding the right approach.
What Didn't Work
Attempt 1: I didn't realize it was hash
1 2 | data.map(&:to_s) |
This fails because Hash#map returns an array of [key, value] pairs, not a hash. Easy mistake when you're thinking about transforming values.
Attempt 2: Looking for a Rails-style helper
1 2 | data.stringify_values |
I assumed this existed because stringify_keys is a thing. Turns out, stringify_values doesn't exist in either Ruby or Rails. Only stringify_keys is available, which converts keys (not values) to strings.
What Works
Attempt 3: The reduce or inject method
1 2 | data.reduce({}) { |acc, (key, value)| acc.merge(key => value.to_s) }
|
This works but feels heavyweight for such a simple transformation. You're manually building up a new hash with reduceand merge. At least my tests are green now.
Attempt 4:Using each_with_object
1 2 | data.each_with_object({}) { |(key, value), hash| hash[key] = value.to_s }
|
Slightly cleaner than reduce, but still requires explicitly managing the accumulator hash.
Attempt 5: Hash#to_h with a block (my preferred solution)
1 2 | data.to_h { |key, value| [key, value.to_s] }
|
Ruby 2.6+ added block support to to_h. You pass a block that receives each key-value pair and returns a two-element array [new_key, new_value]. It's concise and clearly expresses intent: convert this hash by transforming each entry.
Gotcha: This code will still fail with a nested hash. That's for another day, today it was a flat hash.
Comments
Leave a Comment