In JavaScript ES6 we can create objects where variable names become keys like this:
> let a = 'aaa'
'aaa'
> let b = 'bbb'
'bbb'
> { a, b }
{ a:"aaa", b:"bbb" }
Does Ruby have something equivalent for hashes?
Clarification:
Obviously this question regards the shorthand notation. I'm looking for {a,b}
not {a:a,b:b}
.
Although Ruby / Rails doesn't yet support an equivalent to the ES6 shorthand syntax for hashes, there are a few handy idioms already that often come in handy.
Ruby
Consider the following method:
test_splat(a: 4, b: 5, c: 6)
yields"[4, 5, 6]"
Although if you already have a hash such as
hash = { a: 1, b: 2, c: 3 }
, you can simply call it like this:test_splat(hash)
which yields"[1, 2, 3]"
Further
If you have a sub_hash, you can use it alongside other kwargs using the kwarg splat operator
**
. For example if you havesub_hash = { a: 1, b: 2 }
, calling:test_splat(sub_hash)
yieldsArgumentError: missing keyword: c
and calling:
test_splat(sub_hash, c: 3)
yieldsArgumentError: wrong number of arguments (given 1, expected 0)
but using the splat operator
**
, you can do splat thesub_hash
arg:test_splat(**sub_hash, c: 3)
which yields"[1, 2, 3]"
For more reading see https://www.justinweiss.com/articles/fun-with-keyword-arguments/
Rails
The above plus a few extra methods can come in handy for Rails users, particularly in controllers when params are passed in.
Suppose you have an
ActionController::Parameters
object with more attributes than you need and you want a subset. E.g:{ a: 1, b: 2, d: 4 }
. Theslice
method onHash
is very handy here.First, permit your params:
permitted_params = params.permit(:a, :b, :d).to_h.symbolize_keys
.We add
.to_h.symbolize_keys
becauseActionController::Parameters
doesn't supportsymbolize_keys
, and kwargs require the args' keys to be symbols, not strings. So the.to_h
converts it to anActiveSupport::HashWithIndifferentAccess
, and thesymbolize_keys
converts the hash's keys from strings to symbols.Now, calling:
test_splat(**permitted_params, c: 3)
will yieldArgumentError: unknown keyword: d
as expected sinced
isn't a kwarg for thetest_splat
method. Although using slice achieves what we want here:test_splat(**permitted_params.slice(:a, :b), c: 3)
yields"[1, 2, 3]"
No, there is no such shorthand notation.
Short answer no.
Longer answer
Shugo Maeda proposed a patch for this in 2015 (you can read the details about this here: https://bugs.ruby-lang.org/issues/11105).
At the time Matz wasn't into the idea, but might be willing to change his mind in the future.
In the mean time - you can make use of Shugo's patch and patch your own version of Ruby to have ES6 hash literals yourself!
To patch Ruby to add the hashes do the following:
1) Download the patch from here https://gist.github.com/thechrisoshow/1bb5708933d71e0e66a29c03cd31dcc3 (currently works with Ruby 2.5.0)
2) Use RVM to install a patched version of this Ruby. i.e.
Then you can use RVM to select the patched version of Ruby:
(Imphash is short for implicit hash)