Tying long sessions to an IP address is a good way to ensure some security for your users. But inevitably, you’ll want to store that IP. While you could, of course, store it as a string, such as
"126.96.36.199" (called a “dotted quad”), some developers might prefer saving some space and storing it as a compact integer. There’s a right way and a wrong way to do this. The wrong way is as follows:
This is a bad idea because two IP addresses can result in the same integer: 188.8.131.52 and 184.108.40.206 are both valid IPs. The correct way is as follows:
To understand this seemingly obfuscated train wreck, let’s look at the data in this chain after each method call:
'220.127.116.11'.split('.'). #=> ['12', '34', '56', 78'] collect(&:to_i). #=> [12, 34, 56, 78] pack('C*'). #=> "\f\"8N" unpack('N'). #=>  first #=> 203569230
Many developers are unfamiliar with pack and unpack. These allow you to create and extract data into and out of binary-packed strings. In the third method call, you’ll see the result is
"\f\"8N". This strange-looking string is really just 4 bytes of data, the numbers 12, 34, 56, and 78 in binary form, put into a string. We then unpack that 4-byte string into a 4-byte integer (with network byte order).
This is also the same problem solved by the C library method
inet_aton, which is implemented as part of Ruby’s
IPAddr class. Thus, there is a much simpler alternative:
require 'ipaddr' IPAddr.new('18.104.22.168').to_i #=> 203569230
But what fun is that!
PS. Yes, you can have multi-line method chains simply by leaving the dot at the end of the line. Ruby then knows to look for a method call on the next line. Both snippets are valid Ruby! You should, of course, indent appropriately.