Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Destructuring Ruby block arguments dynamically

Tags:

arrays

ruby

block

A recent good article on ruby destructuring defines destructuring as ability to bind a set of variables to a corresponding set of values anywhere that you can normally bind a value to a single variable, and gives an example of block destructuring

triples = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

triples.each { |(first, second, third)| puts second } =>#[2, 5, 8]

In this case we have an idea of the number of elements in the main array and therefore when we provide the arguments first,second,third we can get the corresponding result. So what about if we had an array of arrays whose size is determined at run-time?

triples = [[1, 2, 3], [4, 5, 6], [7, 8, 9],...,[]]

and we would want to get the elements of the first entry for each subarray?

triples.each { |(first, second, third,...,n)| puts first }

what is the best way to create the local variables (first, second, third,...,n) dynamically?

like image 691
eastafri Avatar asked Dec 28 '22 15:12

eastafri


1 Answers

In your specific case, you'd use a splat to collect up everything but the first value:

triples.each { |first, *rest| puts first }
#-----------------------^splat

The *rest notation just collects everything that's left into an Array called rest.

In general, there's not much point to creating an arbitrary number of local variables (second, third, ..., nth) because you wouldn't be able to do anything with them; you could probably whip up a sick mess of evals but we already have a fine and functional Array class so why bother?

like image 111
mu is too short Avatar answered Dec 30 '22 05:12

mu is too short