Torturing Ruby (and laughing at your own code) 10

Posted by andy

While cleaning up some code I ran across some obscure code of mine from my Ruby youth. I remembered reading about an ultra cool Ruby tool the other day so I decided to give my code a good flogging. The victim for tonight is a method used to slice ID numbers into chunks of at most 4 characters long. This is required to overcome the typical Linux file system limitation of at most 32000 entries per directory. In this case the project stores roughly a million thumbnail images on disk. We start with the original piece of code:

1
2
3
4
5
6
7
8
def splice_number(number, part_size = 4)
  n = number.to_s
  r = []
  return r if n.size.zero?
  (n.size / part_size).times { |t| r << n[(t*part_size)..((t+1)*part_size-1)] }
  r << n[-(n.size % part_size)..n.size] if (n.size % part_size) > 0
  r
end

Ah yes, WTF was I thinking when I wrote this? Who cares, it seemed very clever then! What does Flog think about this?

Total score = 28.35

none#splice_number: (28)
     7: size
     3: *
     2: %
     2: []
     2: <<
     1: +
     1: -@
     1: -
     1: /
     1: lit_fixnum
     1: zero?
     1: >
     1: to_s
     1: times

Pretty good score. Now it’s time for some torturing. Say hello to my little friend: unpack!

1
2
3
4
def splice_number(number, part_size = 4)
  n = number.to_s
  n.unpack("a#{part_size}" * (n.size / part_size) + ((n.size % part_size == 0) ? "" : "a*"))
end

Flog?

Total score = 13.05

none#splice_number: (13)
     3: size
     1: %
     1: /
     1: ==
     1: *
     1: +
     1: to_s
     1: unpack
     0: lit_fixnum

Yeow, well over half the pain gone!! Perhaps we can still improve by being less clever?

1
2
3
4
5
6
def splice_number(number, part_size = 4)
  n = number.to_s
  r = n.unpack("a#{part_size}" * (n.size / part_size) + "a*")
  r.delete("")
  r
end

More lines, but less code! Hmm?

Total score = 9.25

none#splice_number: (9)
     1: size
     1: /
     1: *
     1: +
     1: delete
     1: to_s
     1: unpack
     0: lit_fixnum
Weeh, a full 2/3 of the pain flogged out of the code! That’s all the torture I’ll do for tonight..

Update: Okay, couldn’t help myself, last blow:

1
2
3
4
5
6
7
8
def splice_number(number, part_size = 4)
  n = number.to_s
  p = "a#{part_size}"
  t = n.size / part_size
  r = n.unpack(p * t + "a*")
  r.delete("")
  r
end
With score:
Total score = 8.05

none#splice_number: (8)
     1: *
     1: size
     1: +
     1: delete
     1: to_s
     1: /
     1: unpack
     0: lit_fixnum

Done..