<commit_before>= SimpleStateMachine

A Ruby Statemachine that focuses on events instead of states.

A state machine should help you:
- Encapsulate state,
- Guard state transitions,
- Make it trivial to add state transitions to any method.

Instead of using a DSL to define events, we use a different approach.
We have a simple DSL to decorate existing methods with logic that guards 
state transitions.

==== example

  def activate_account(activation_code)
    if activation_code_invalid?(activation_code)
      errors.add(:activation_code, 'Invalid')
    end
  end
  event :activate_account, :pending => :active


This has a couple of advantages:
- Encapsulate state transitions (no need for :guards),
- Arguments can be passed to 'events',
- 'events' can return a value it's just a method,
- Validation errors can be set on the model if you are using ActiveRecord / ActiveModel,

== Example

To add a state machine:
- extend SimpleStateMachine
- set the initial state
- turn methods into events

  class LampWithHotelSwitch
    
    extend SimpleStateMachine
    
    def initialize
      self.state = :off
    end
    
    def push_switch_1
      puts 'pushed switch 1 #{state}'
    end
    event :push_switch_1, :off => :on,
                          :on  => :off
    
    def push_switch_2
      puts 'pushed switch 2 #{state}'
    end
    event :push_switch_2, :off => :on,
                          :on  => :off
    
  end

== ActiveRecord Example

To add a state machine with ActiveRecord persistence:
- extend SimpleStateMachine::ActiveRecord,
- set the initial state in after_initialize,
- turn methods into events

  class User < ActiveRecord::Base
     
    extend SimpleStateMachine::ActiveRecord
    
    def after_initialize
      self.state ||= 'new'
      # if you get an ActiveRecord::MissingAttributeError
      # you'll probably need to do (http://bit.ly/35q23b):
      #   write_attribute(:state, "new") unless read_attribute(:state)
    end
    
    def invite
      self.activation_code = Digest::SHA1.hexdigest("salt #{Time.now.to_f}")
      #send_activation_email
    end
    event :invite, :new => :invited
    
    def confirm_invitation activation_code
      if self.activation_code != activation_code
        errors.add 'activation_code', 'is invalid'
      end
    end
    event :confirm_invitation, :invited => :active
    
  end<commit_msg>Improved readme<commit_after>= SimpleStateMachine

A Ruby Statemachine that focuses on events instead of states.

A state machine should help you:
- Encapsulate state,
- Guard state transitions,
- Make it trivial to add state transitions to any method.

Instead of using a DSL to define events, we use a different approach.
We have a simple DSL to decorate existing methods with logic that guards 
state transitions.

==== example

  def activate_account(activation_code)
    if activation_code_invalid?(activation_code)
      errors.add(:activation_code, 'Invalid')
    end
  end
  event :activate_account, :pending => :active


This has a couple of advantages:
- Encapsulate state transitions (no need for :guards),
- Arguments can be passed to 'events',
- 'events' can return a value it's just a method,
- Validation errors can be set on the model if you are using ActiveRecord / ActiveModel,

== Example

To add a state machine:
- extend SimpleStateMachine
- set the initial state
- turn methods into events

    class LampWithHotelSwitch
      
      extend SimpleStateMachine
      
      def initialize
        self.state = :off
      end
      
      def push_switch_1
        puts 'pushed switch 1 #{state}'
      end
      event :push_switch_1, :off => :on,
                            :on  => :off
      
      def push_switch_2
        puts 'pushed switch 2 #{state}'
      end
      event :push_switch_2, :off => :on,
                            :on  => :off
      
    end

== ActiveRecord Example

To add a state machine with ActiveRecord persistence:
- extend SimpleStateMachine::ActiveRecord,
- set the initial state in after_initialize,
- turn methods into events

    class User < ActiveRecord::Base
       
      extend SimpleStateMachine::ActiveRecord
      
      def after_initialize
        self.state ||= 'new'
        # if you get an ActiveRecord::MissingAttributeError
        # you'll probably need to do (http://bit.ly/35q23b):
        #   write_attribute(:state, "new") unless read_attribute(:state)
      end
      
      def invite
        self.activation_code = Digest::SHA1.hexdigest("salt #{Time.now.to_f}")
        #send_activation_email
      end
      event :invite, :new => :invited
      
      def confirm_invitation activation_code
        if self.activation_code != activation_code
          errors.add 'activation_code', 'is invalid'
        end
      end
      event :confirm_invitation, :invited => :active
      
    end
{'fraction_non_alphanumeric': 0.07272727272727272, 'fraction_numerical': 0.004545454545454545, 'mean_word_length': 2.7295839753466873, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1111640', 'n_tokens_mistral': 1365, 'n_tokens_neox': 1321, 'n_words': 490}