gocardless / statesman

A statesmanlike state machine library.
https://gocardless.com/blog/statesman/
MIT License
1.79k stars 163 forks source link

Feature proposal: Allow accessing states as state machine constant #513

Open stephannv opened 1 year ago

stephannv commented 1 year ago

Would be nice if .state method defined a constant using the state name. eg.:

class OrderStateMachine
  include Statesman::Machine

  state :pending
  state :failed
end

OrderStateMachine::PENDING # => "pending"
OrderStateMachine::FAILED # => "failed"

This way we can detect typos and changed states early:

Order.new(state: :peding) # ok
Order.in_state(:peding) # ok

Order.new(state: OrderStateMachine::PEDING) # uninitialized constant OrderStateMachine::PEDING (NameError)
Order.in_state(OrderStateMachine::PEDING) # uninitialized constant OrderStateMachine::PEDING (NameError)

What do you think? Would this be useful for more people?

dmitry commented 1 year ago

Useful from the perspective of refactoring and finding the usage, as in our codebase some of the states from different state machines are equally named. The main question should it be a symbol or a string. And what about the case, when the constant name is already defined? Should it redefine it quietly, raise an error or show a message while the application boots?!

stephannv commented 1 year ago

@dmitry following .initial_state, #current_state, .states return type, it should be a string. About constant name conflict, I think it should just warn user about it.