by Leon Rosenshein

The Scouting Rule

Try and leave this world a little better than you found it.

        – Lord Baden-Powell

The scouts have as one of their tenets to not just clean up the campsite after themselves, but to make it a little cleaner/better. While we might not be scouts now, that idea applies to us too. It’s also a great way to manage technical debt.

Development velocity is important. The speed at which we can add features/capabilitiesdrives how quickly we can add value. The trick is managing both instantaneous long-term velocity. It’s easy to always make the choice that maximizes instantaneous velocity, but over time you often end up going slower overall.

One way to combat that is to clean things up while you’re working on things. The other day I was tracking down a bug in the infra tool that caused a crash if there was no pre-existing config file. The fix itself was simple. Just ensure the needed directory structure was in place before trying to create the config file. But while I was debugging I ran into this little bit of code

func (fileSystem) Exists(path string) (bool, error) {
  _, err := os.Stat(path)
  if err != nil && !os.IsNotExist(err) {
    return false, err
  return err == nil, nil
}

Now that is correct, but it took me 10 minutes to really be confident that it was. So I changed it to be

// If Stat works the file exists. If Stat errors AND the error is an IsNotExist error then the file doesn't
// exist. For any other error we say the file doesn't exist and return the error
func (fileSystem) Exists(path string) (bool, error) {
  _, err := os.Stat(path)
  if err != nil {
    if os.IsNotExist(err) {
      return false, nil
    }
    return false, err
  }
  return true, nil
}

That’s much easier to read, and the next person who has to go in there will thank me. It’s probably going to be me, and I’ll still be thankful. BTW, there’s an even better way to rewrite it, but that will wait until I have a free moment or find myself in there again.

So, next time you’re in the code and you see something not quite right or that should be refactored you should just do it right? Well, … it depends. It depends on how big a refactor it is, if it’s going to make doing what you went into the code to do easier, and what the next known things you’ll need to do are. If it is directly related and will make you more efficient then you probably should. If it will be helpful next week then maybe. If you think you’ll need it in 6 months then you should probably document the issue and not fix it now.

And as an aside, when you’re doing refactoring changes, do your best to keep them separate from the change they’re enabling. It’s much easier to test/review a pure refactor PR that isn’t supposed to have any runtime impact and a change-inducing PR separately.

https://docs.google.com/document/d/1QzFcWc6TAbI1APOMv-9e8VYZtm08DoLCJyEQ2WUDLKE/edit#heading=h.xcbfdi4m6jyn
https://www.stepsize.com/blog/how-to-be-an-effective-boy-girl-scout-engineer