4 ms·
> options = { a: 'b' } > { c: 'd', options } # => { :c => "d", :a => "b" } > I don’t know when this is useful. Ah! When I was learning Ruby after being
by __david__ 11y ago
> options = { a: 'b' }
> { c: 'd', options } # => { :c => "d", :a => "b" }
> I don’t know when this is useful.
Ah! When I was learning Ruby after being a long time perl user, this was the one huge missing feature that I longed for. Perl splats automatically (you have to use refs if you don't want it to), and that leads to nice option construction:
@opts = ($some_flag1 ? (option1 => $some_flag1) : (),
$some_flag2 ? (option2 => { a => 1 }) : (),
$some_flag3 ? (option3 => [ 1,2,3 ]) : (),
$some_flag4 ? (option4 => [$some_flag4, 1]) : ())
But it was annoying in Ruby. The best way I found previously was with a bunch of chained .merges, one for each option:
opts = {}.merge(some_flag1 ? {:option1 => $some_flag1} : {})
.merge(some_flag2 ? {:option2 => { :a => 1 }} : {})
.merge(some_flag3 ? {:option3 => [ 1,2,3 ]} : {})
.merge(some_flag4 ? {:option4 => [$some_flag4, 1]} : {})
Ugly and verbose compared to the perl (which is usually not the case in perl vs ruby). This new syntax allows for:
opts = {**(some_flag1 ? {:option1 => $some_flag1} : {}),
**(some_flag2 ? {:option2 => { :a => 1 }} : {}),
**(some_flag3 ? {:option3 => [ 1,2,3 ]} : {}),
**(some_flag4 ? {:option4 => [$some_flag4, 1]} : {})}
Which looks only marginally better, but allows nice things like interleaving optional and non-optional arguments:
opts = {**(some_flag1 ? {:option1 => $some_flag1} : {}),
:option1_related => "xyz",
**(some_flag2 ? {:option2 => { :a => 1 }} : {}),
**(some_flag3 ? {:option3 => [ 1,2,3 ]} : {}),
:option4_related1 => "xyz",
:option4_related2 => "pdq",
:option4_related3 => "abc",
:option4_related4 => "123",
**(some_flag4 ? {:option4 => [$some_flag4, 1]} : {})}
That's quite nice.
- rudolf0 11y agoThis is also now in Python 3, both for single and double splats.