Enums in Ruby

Our enum type ServerState has an underlying int type.

class ServerState
  attr_reader :state
  def initialize(state)
    @state = state
  end

  def to_s
    NAME_MAP[@state]
  end

  IDLE       = new(0)
  CONNECTED  = new(1)
  ERROR      = new(2)
  RETRYING   = new(3)

  NAME_MAP = {
    IDLE.state       => "idle",
    CONNECTED.state  => "connected",
    ERROR.state      => "error",
    RETRYING.state   => "retrying"
  }
end

By implementing the to_s method in our enum class, we can convert values of ServerState to strings.

def transition(state)
  case state
  when ServerState::IDLE.state
    ServerState::CONNECTED
  when ServerState::CONNECTED.state, ServerState::RETRYING.state
    ServerState::IDLE
  when ServerState::ERROR.state
    ServerState::ERROR
  else
    raise "unknown state: #{state}"
  end
end

def main
  ns = transition(ServerState::IDLE.state)
  puts ns

  ns2 = transition(ns.state)
  puts ns2
end

main

The transition function emulates a state transition for a server; it takes the existing state and returns a new state.

$ ruby enums.rb
connected
idle