patternrubyMinor
Evaluating a dotted quad IP address has clumsy use of inject/fold
Viewed 0 times
addressdottedfoldhasclumsyinjectusequadevaluating
Problem
I wrote this to consume valid IPv4 addresses in dotted-quad decimal form:
But my chain of
Firstly, Ruby won't let me match (aka desctructure) the pair yielded by each_with_index like this
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?
Please set aside the improvement of multiplying the accumulator by 256 at each inject/reduce step, as that eliminates
I also welcome reviews from users of non-Ruby collections libraries. (FYI collect is map in some other languages.)
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))
end
endBut 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))
end
octets.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.)
Solution
The correct Ruby-way (also Perl and others) is to use
pack/unpack, since low-level bytes job is what they are implemented for.def dotted_ip_to_num ip
ip.split(".").map(&:to_i).pack("C*").unpack("N")[0]
endCode Snippets
def dotted_ip_to_num ip
ip.split(".").map(&:to_i).pack("C*").unpack("N")[0]
endContext
StackExchange Code Review Q#57657, answer score: 3
Revisions (0)
No revisions yet.