Learning to Code Like a Rubist

Code Monkeys

Today I spent some time fixing a bug, and while I was in the code, I wanted to see if my manager was right - that I was writing code that no one on the team liked working with. After all, I'm new to writing in ruby, and there's a unique style, I've come to learn, and I wanted to see if I've been doing it right, or maybe not right enough. I had something like this in my code:

  if meetings.empty?
    ru = fills * misses / factor
    fu = (1.0 / ru) * fill[0]
  else
    ru = fills.map { |f| f * misses / factor }
    fu = ru.map { |r| 1.0 * fill[0] / r }
  end
 
  all_zips = location.map { |l| l['zip_code'] }.compact.uniq
  {
    :ru => ru,
    :fu => fu
  }

Now, in truth, this makes no sense and I had about 10 lines in both branches of the 'if' statement, but the gist was that if the data was a constant, do one set of calculations, and if it was a vector, then do a slightly different set, but along the same lines as the single-valued calculations.

Nothing complex.

But it seems that The Ruby Way is to make anything that's more than a line or two into a new function - even if it's significantly expanding the lines-of-code in the file. So contrary to my prevailing understanding of the reasons for this extreme composition, it's really about the complexity of the code.

I was talking to a consultant new to the group, and his statement was that he trusted the code to do what it said it was doing, and by making the methods very small, and well-defined names, it was easy to understand what they were doing.

I asked him about debugging, and his statement was again about trust.

I was shocked. On so many levels.

First, that trust had anything to do with debugging. Second, that they felt this code was too complex, and required refactoring.

It's a few lines - say 10, and it's a series of calculations. There's no savings in making it functions. It's adding stack calls, tests on the input values, and re-testing the values that caused the branch in the first place. It was horribly less efficient than before, but that's what they wanted.

It's back to the "CPU cycles are Cheap - Dev cycles are Expensive" - Hogwash that I've heard before, and don't agree with in the slightest bit. Nothing is cheap. Everything is expensive, and it's all about balancing the costs of different factors into the final design. There's no free lunch, but it seems that fact hasn't found the Rubists yet.

Secondly, you never trust code in the debugging. You 'single-step' all the code when you have a bug to find out where it lies. If you trust code, you're going to get burned. Guaranteed. Debugging is a thoughtful exercise. You have to think what should happen, and then watch and see exactly what does. This means you can't take anything for granted. Not a single thing. That they would makes me very nervous that "fixes" on their part aren't going to be fixes at all. They'll patch or "refactor" until the bug goes away, but that's not the same as really fixing it. It might just pop up somewhere else.

Finally, I can't imagine that I'm going to be able to write code like this long-term. I don't see it as overly-complex, so I'm not going to think that it needs refactoring. If I take the absurd approach that every calculation is a method, I know I'll be wrong on the other extreme, so I can't just pretend to know what to do.

I'm frustrated, and I feel like giving up. It's been a hard day, and by all measures I seem to be incapable of getting the right mindset to write this code like the rest of the team. They aren't happy with my code, and they aren't willing to put in the hours to write it before I do. So they are going to complain about it, and I'm going to be powerless to understand their mindset properly to write code like they would.

I wish I knew what I could do to fix this problem…