I wrote this to consume valid IPv4 addresses in dotted-quad decimal form:def dotted_ip_to_num ip  strings = ip.split('.').reverse  strings.each_with_index.inject(0) do |sum, pair|    str, i = pair    sum + str.to_i * (2 ** (i * 8))  endendBut my chain of each_with_index and inject (aka left-fold or reduce) looks clumsy to me.Firstly, Ruby won't let me match (aka desctructure) the pair yielded by each_with_index like this |sum, str, i| or this |sum, [str, i]|. Did I miss something? So, I do this on a line of its own (line 4.)Secondly, although the message chain is only 2 messages, is it so complex in this case that I should split it up to do the summation as an extra line, like this?octets = strings.each_with_index.collect do |str, i|  str.to_i * (2 ** (i * 8))endoctets.inject(0, :+)  Please set aside the improvement of multiplying the accumulator by 256 at each inject/reduce step, as that eliminates each_with_index entirely, and means I won't get the answer to my two main questions.I also welcome reviews from users of non-Ruby collections libraries. (FYI collect is map in some other languages.)
Evaluating a dotted quad IP address has clumsy use of inject/fold
ruby;parsing;functional programming;collections;ip address
Some notes:As you say in your answer, you can unpack block arguments with the syntax |arg1, (arg2, arg3)|.I'd always write parentheses in the method definition, it looks more clear (subjective, of course).Instead of doing two things inside the reduce block, split it in a map + simpler reduce.I'd write:def dotted_ip_to_num(ip)  xs = ip.split('.').map(&:to_i).reverse  xs.map.with_index { |x, idx| x * (256**idx) }.reduce(0, :+)end