leifg leifg - 2 months ago 10
Ruby Question

Array() applied to hashes?

Recently I stumbled upon "The Elements of Style in Ruby #3: Make Sure Something Is an Array".

TL;DR: The Method

Array()
in Ruby converts anything you put in, into an array and tries to guess what the correct outcome should be:

Array(1) # => [1]
Array([1,2]) # => [1,2]
Array(nil) # => []


So what does
Array({a: :b})
return? I would assume it returns an array with the hash as a value:
[{a: :b}]
.

However, the hash is converted directly into an array:
[:a, :b]
.

I don't just want to put a hash into an array (
[{a: :b}]
). I'd like to have functionality that returns an array no matter what I put in.
Array()
already does that, but it converts a hash to an array in a way that I don't expect.

So, basically the functionality should look like this:

NewFancyArrayMethod({a: :b}) # => [{a: :b}]
NewFancyArrayMethod([{a: :b}, {c: :d}]) # => [{a: :b}, {c: :d}]


The second part is already fulfilled by
Array()
.

I know I can do something like
values = [values] unless values.is_a? Array
, like the article points out. However, I would rather have a method that abstracts this conversion from me as
Array()
already does. The only problem is that
Array()
treats a hash differently than any other "single" value (String, Integer, Object, etc.). I simply don't want different handling for different cases.

Answer

As Frederick Cheung pointed out in a commend, the method Array#wrap does exactly what I desire:

Array.wrap({a: :b})
# => [{a: :b}]

Unfortunately this method is only part of ActiveSupport, so it can't be used in plain Ruby projects.