Terminator: Death to the (State) Machines III — End?

Eumir Gaspar
ITNEXT
Published in
2 min readMar 12, 2018

--

Note: If you haven’t read part 1 and part 2, please do so! It gives you some background on why I wrote this and some context for the solution I will be discussing in a bit.

Click here to share this article on LinkedIn »

Previously…

We have started a revolution (at least in our team) against the state machines. Most of the state machine logic has been replaced now and the aftermath is almost the same amount of lines of code — but much more explicit, obvious, and deliberate. It is way easier to read now and tech debt has fallen like a ponzi coin.

Where to next?

This has been the question nagging us since then. Do we keep marching and eventually remove the state machine gem? Will we be implementing our own state machines from now on? Up to what point will we be “rolling our own”?

It has been a fun journey. Refactoring and cleaning up code just excites me as writing new code. I think that we can co-exist with the machines peacefully. I still like the DSL that they provide — it’s the transitions that will kill you and bury you in tech debt.

There are two major things that I don’t like about these gems:

  • Before, after, around transitions — these are just as bad as callbacks. Just no.
  • Methods, validations, variables that only exist on a certain state:
This is very annoying to debug, seriously. Avoid like the plague if possible. If not, good luck.

Unfortunately, these are the main functionalities of such gems, which brings me back to the question: do we really need it?

I think some teams can use it, especially when bootstrapping an app. Don’t underestimate the power of the DSL — they’re pretty sleek, well thought of and robust. It just starts getting hairy once you keep adding more transitions and custom stuff.

If you wanted to just use a basic state machine, then this is the perfect use case.

But what IS a basic state machine?

I would define one as something that does not need any specific logic per state. It should also not have any triggers upon switching to a certain state. My most basic use case would be it changes state from one to another and that’s it. There CAN be guard clauses for which state can transition to which like an actual finite state machine but that’s it. No callbacks. No custom stuff. Let’s count the magical automatic scopes as a bonus.

In conclusion, these state machine gems are still relevant and useful, but I think they should be used with care and with the future in mind. We don’t want to be in a future ruled by the machines. We want to always be in control of our code and depending on a very advanced machine can spell trouble if we’re not careful.

--

--

Crypto enthusiast. Ruby developer by day, CTO/Elixir developer at night. SASS lover all day, every day.