Live data from Hacker News

State Machines in Ruby: An Introduction

blog.appsignal.com

31–40 of 42 posts

Re: State Machines in Ruby: An Introduction

#31
post #15
post #4

Counterpoint: State machines in Ruby should be used sparingly, and only when necessary, because they start out quick and easy, but almost always grow into things that are big, ugly, and difficult to refactor or remove. Here are somebody's notes from a Railsconf talk that made this point, plus a link to the video: https://gist.github.com/benoittgt/05521e272e13c7b7c9c89eb4a9... But the short version is the takeaway quo…

Of all the things I've seen in my time writing software I can qualify that some of the most fucked up things involved state machines. The worst of which was a 200 state hand written one in C for an embedded measurement system. There was no documentation, no comments and the states were numbered rather than named. The guy who wrote it originally was "anti RTOS" and had died after riding his motorbike recklessly leavin…

I call this crap enterprise grade spaghetti code. It's "structured programming" with dynamic dispatch of gotos.

Re: State Machines in Ruby: An Introduction

#32

A lot of the comments here are rails oriented and anti state machine. In the context of rails that may make sense, but I do a lot of non rails ruby, and non object oriented Dev style, and state machines are a great way to write solid systems where the allowed state and transitions are explicit and easy to reason with.

Would you mind sharing a little example of what you mean by non-OOP Ruby code with state machines?

Sure. I am working on the firmware for a camera. Believe it or not it's a bunch of ruby services coordinated via redis pubsub. But at the core is the main system state which is a service in itself which is the main state machine.

This pattern is something which I've evolved over the years and it's fantastic (if I do say so myself).

Re: State Machines in Ruby: An Introduction

#33
post #28

A lot of the comments here are rails oriented and anti state machine. In the context of rails that may make sense, but I do a lot of non rails ruby, and non object oriented Dev style, and state machines are a great way to write solid systems where the allowed state and transitions are explicit and easy to reason with.

Honestly state machines are fantastic in Rails too. My last company built Statesman ( https://github.com/gocardless/statesman/ ) and being able to lean on it to prevent you getting into invalid states is fantastic. You also get the bonus of tracking the history of states your resources went through (which is especially useful when you're dealing with payments). At some point you'll have to think about query performan…

In a previous life I implemented a business system in rails with a core state machine. The staff who used it could fundamentally understand the states and transitions, bringing them closer to understanding how the whole system worked. Not all benefits or costs of a technique are limited to the developer

Re: State Machines in Ruby: An Introduction

#34

A lot of the comments here are rails oriented and anti state machine. In the context of rails that may make sense, but I do a lot of non rails ruby, and non object oriented Dev style, and state machines are a great way to write solid systems where the allowed state and transitions are explicit and easy to reason with.

A pretty big +1 to this. My team (at Crunchy Data building Crunchy Bridge[1]) and similar teams at prior Citus Data and Heroku did a lot of Ruby and a lot of state machines. In all cases it was actually less Rails, but that may be because the team really prefers sequel as the ORM to ActiveRecord, though Rails does a bunch that doesn't really apply to such a workflow. We wrote about some of how we used state machines…

Clearly some quite senior developers there. Makes me wonder if the people hating on state machines have been at the mercy of junior devs or people trying it out for the first time, instead of a well planned state machine by someone with experience.

Full disclosure, I think I wrote my first state machine in around 1996. So yea... Grey hair etc. Also it was a big part of my computer science degree, studied formally, so perhaps that's why I'm biased in favour of them.

Re: State Machines in Ruby: An Introduction

#35
post #20
post #7

Earlier quoted context omitted.

Funny, I have spent a ton of time around Rails code where I dearly wished we had a state machine, because the alternative was an unorganized cluster of home-grown "state transition" glue without any consistent way of handling it, with all the weird-ass edge cases and split-brain BS that come with it.

The quip I like best for this is: “Any sufficiently complicated model class contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of a state machine.” Lots of models I've encountered eschew being organized as state machines in favour of having "if salad" strewn throughout their code. That being said, refactoring to a simple state machine and trying to maintain it as such in perpetuity isn'…

State machines aren’t exactly rocket science though, I don’t necessarily think writing one for your specific preferences/use cases is as bad of an idea as, say, writing your own ORM. It’s a pretty well understood concept.

Re: State Machines in Ruby: An Introduction

#36
post #3

I've seen a few large Rails codebases that included a state machine library like mentioned in the article. Every single one was worse because of it. It pushes the code down a path where hidden hooks run when magic methods are called. At this point in my career I'm just done with that type of "clever" code. The article starts with examples that just define the state machine by hand. This is a much better approach and…

Came here to write this.

Using explicit state action services, which are well tested and intentionally invoked are the ways to go. They encapsulate the code, and don't create these callback hells when things inevitably get complex.

Re: State Machines in Ruby: An Introduction

#37

I worked at a business (in ruby) where the entire core logic of the app was a state machine, as an idea the thought was good, a state machine modeled order flows pretty well, but in practice it was very slow and the amount of side effects that had to be considered as the business grew just compounded this. It got to the point where this state machine approach was a real bottleneck and though I left before it was reso…

> but in practice it was very slow

How in the world is updating a column from "in cart" to "purchased" to "complete" slow? There are only three things a state machine has to do:

  1. Determine if the event can happen
  2. Set the record to the new state
  3. Call lifecycle hooks
None of that should be "very slow".

Re: State Machines in Ruby: An Introduction

#38
Seems to be a lot of anti-state machine comments here. Are these people trying to use state machines to model their entire application state? The example used in the article is a very practical finite state machine centered around order processing. It's very unlikely these steps in an order lifecycle are going to change significantly. I suspect a lot of organizations jumped on all-in with state machines when they got a resurgence in popularity with x-state library etc. Trying to model your entire application as a state machine just so you can show off an incomprehensible state chart or something is a recipe for disaster.

Re: State Machines in Ruby: An Introduction

#39

Seems to be a lot of anti-state machine comments here. Are these people trying to use state machines to model their entire application state? The example used in the article is a very practical finite state machine centered around order processing. It's very unlikely these steps in an order lifecycle are going to change significantly. I suspect a lot of organizations jumped on all-in with state machines when they got…

Creator of XState here - I agree. State machines and statecharts should be used to model parts of your application that need it, and they can potentially communicate with each other. Fitting the entire app in a single state machine is just like fitting all of the app logic in a single function; it's going to be incomprehensible.

Re: State Machines in Ruby: An Introduction

#40
post #20

Earlier quoted context omitted.

The quip I like best for this is: “Any sufficiently complicated model class contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of a state machine.” Lots of models I've encountered eschew being organized as state machines in favour of having "if salad" strewn throughout their code. That being said, refactoring to a simple state machine and trying to maintain it as such in perpetuity isn'…

State machines aren’t exactly rocket science though, I don’t necessarily think writing one for your specific preferences/use cases is as bad of an idea as, say, writing your own ORM. It’s a pretty well understood concept.

They aren’t exactly rocket science, agreed, but there’s an interesting trap here:

Implementing classes on top of pre-ES2015 JS wasn’t exactly rocket science either, so there was a “Cambrian Explosion” of home-grown implementations and OSS libraries all over the place. Frameworks like Ember.js rolled their own too, and everything was incompatible with everything else, plus while the basic principles were the same, the details differed from implementation to implementation.

And when organizations are rolling their own, they tend to do just enough to serve their immediate needs. As their needs grow, different internal contributors add patches and bodges to the implementation, using different approaches.

Over the long haul, even though the concept is simple enough to roll your own state machine, it’s often a win to build on top of something which is well-supported and can grow with your organization.

Just as it was with classes in JS.

Post reply on HN