HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyMinor

Evaluating a dotted quad IP address has clumsy use of inject/fold

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
addressdottedfoldhasclumsyinjectusequadevaluating

Problem

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))
  end
end


But 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]
end

Code Snippets

def dotted_ip_to_num ip
    ip.split(".").map(&:to_i).pack("C*").unpack("N")[0]
end

Context

StackExchange Code Review Q#57657, answer score: 3

Revisions (0)

No revisions yet.