<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>8th Light Blog: Understanding Statemachines, Part 2: Actions</title>
    <link>http://blog.8thlight.com/articles/2006/11/30/understanding-statemachines-part-2-actions</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>In the minds of the craftsmen...</description>
    <item>
      <title>Understanding Statemachines, Part 2: Actions</title>
      <description>&lt;h3&gt;Actions&lt;/h3&gt;

&lt;p&gt;Part 1 demonstrated how to build states and transitions.  Add some actions to that and you&amp;#8217;ve got a truly useful statemachine.  Actions allow statemachines to perform operations at various point during execution. There are two models for incorporating actions into statemachines.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mealy:&lt;/strong&gt; A Mealy machine performs actions on transitions.  Each transition in a statemachine may invoke a unique action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Moore:&lt;/strong&gt; A Moore machine performs actions when entering a state.  Each state may have it&amp;#8217;s own entry action.&lt;/p&gt;

&lt;p&gt;Mealy and Moore machines each have advantages and disadvantages.  But one great advantage of both it that they are not mutually exclusive.  If we use both models, and toss in some exit actions, we&amp;#8217;ve got it made!&lt;/p&gt;

&lt;h3&gt;Example:&lt;/h3&gt;

&lt;p&gt;Remember the vending machine statemachine.  It had some problems.  Adding some actions will solve many of them.  Here&amp;#8217;s the same statemachine with actions.&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img style="border: 1px solid black" src="/files/vending_machine2.png"&gt;&lt;br/&gt;&lt;b&gt;The Vending Machine Statemachine Diagram, Version 2&lt;/b&gt;&lt;/div&gt;

&lt;p&gt;You can see I&amp;#8217;ve added three transition actions (the Mealy type).  Check out the transition from &lt;em&gt;Waiting&lt;/em&gt; to &lt;em&gt;Paid&lt;/em&gt;.  When this transition is triggered the &lt;em&gt;activate&lt;/em&gt; action will be called which will activate the hardware that dispenses goodies.  Also, when a selection is made, transitioning from &lt;em&gt;Paid&lt;/em&gt; to &lt;em&gt;Waiting&lt;/em&gt;, the &lt;em&gt;release&lt;/em&gt; action will cause the hardware to release the selected product.  Finally, this version of the vending machine won&amp;#8217;t steal your money any more.  When an extra dollar is inserted, the &lt;em&gt;refund&lt;/em&gt; event is invoked and the dollar is refunded.&lt;/p&gt;

&lt;p&gt;Notice that the &lt;em&gt;Waiting&lt;/em&gt; state has an entry action (Moore type) and an exit action.  When ever the &lt;em&gt;Waiting&lt;/em&gt; states is entered, the &lt;em&gt;sales_mode&lt;/em&gt; action is invoked.  The intent of this action is to make the vending machine blink or flash or scroll text; whatever it takes to attract customers.  When the &lt;em&gt;Waiting&lt;/em&gt; state is exited, the vending will go into &lt;em&gt;operation_mode&lt;/em&gt; where all the blinking stops so the customer do business.&lt;/p&gt;

&lt;h3&gt;Implementation:&lt;/h3&gt;

&lt;p&gt;Here&amp;#8217;s how the new vending machine can be implemented in Ruby:&lt;/p&gt;

&lt;pre&gt;vending_machine = Statemachine.build do
  state :waiting do
    event :dollar, :paid, :activate
    event :selection, :waiting
    on_entry :sales_mode
    on_exit :operation_mode
  end
  trans :paid, :selection, :waiting, :release
  trans :paid, :dollar, :paid, :refund
  context VendingMachineContext.new
end&lt;/pre&gt;

&lt;p&gt;There are several new tricks to learn here.  First is the &lt;code&gt;state&lt;/code&gt; method.  This is the formal syntax for declaring a state.  The informal syntax is the &lt;code&gt;trans&lt;/code&gt; method which we&amp;#8217;ve already seen.  The &lt;code&gt;state&lt;/code&gt; method requires the state id and an option block.  Every method invoked within the block is applied to the state being declared.  &lt;/p&gt;

&lt;p&gt;With a &lt;code&gt;state&lt;/code&gt; block you may declare events, entry actions, and exit actions.  The &lt;code&gt;event&lt;/code&gt; method is used to declare transition out of the current state.  Its parameters are the event, destination state, and an optional action. The &lt;code&gt;on_entry&lt;/code&gt; and &lt;code&gt;on_exit&lt;/code&gt; methods are straight forward.  They take one parameter: an action. (See below for more on action syntax)&lt;/p&gt;

&lt;p&gt;After the &lt;code&gt;waiting&lt;/code&gt; state declaration we see the familiar calls to &lt;code&gt;trans&lt;/code&gt;.        The &lt;code&gt;trans&lt;/code&gt; method takes an option 4th action parameter.  You can see that the &lt;code&gt;release&lt;/code&gt; and &lt;code&gt;refund&lt;/code&gt; actions were added this way.&lt;/p&gt;

&lt;h3&gt;Context:&lt;/h3&gt;

&lt;p&gt;The final line sets the context of the statemachine. This is an interesting aspect.  Every statemachine may have a context and if your statemachine has actions, you should definitely give it a context.  Every action of a statemachine will be executed within its context object.  We&amp;#8217;ll discuss this more later.&lt;/p&gt;

&lt;p&gt;Here is a simple context for the vending machine statemachine.&lt;/p&gt;

&lt;pre&gt;class VendingMachineContext

  def activate
    puts "activating"
  end

  def release(product)
    puts "releasing product: #{product}"
  end

  def refund
    puts "refuding dollar"
  end

  def sales_mode
    puts "going into sales mode"
  end

  def operation_mode
    puts "going into operation mode"
  end

end&lt;/pre&gt;

&lt;h3&gt;Action Declarations:&lt;/h3&gt;

&lt;p&gt;With the statemachine gem, actions can be declared in any of three forms: Symbols, String, or Block.  &lt;/p&gt;

&lt;p&gt;When the action is a &lt;strong&gt;Symbol&lt;/strong&gt;, (&lt;code&gt;on_entry :sales_mode&lt;/code&gt;) it is assumes that there is a method by the same name on the &lt;code&gt;context&lt;/code&gt; class.  This method will be invoked.  Any parameters in with the event will be passed along to the invoked method. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;String actions&lt;/strong&gt; should contains ruby code (&lt;code&gt;on_entry "puts 'entering sales mode'"&lt;/code&gt;). The string will use invoked with in the &lt;code&gt;context&lt;/code&gt; object using &lt;code&gt;instance_eval&lt;/code&gt;.  Strings allow quick and dirty actions without the overhead of defining methods on your &lt;code&gt;context&lt;/code&gt; class.  The disadvantage of String actions is that they cannot accept parameters. &lt;/p&gt;

&lt;p&gt;If the action is a &lt;strong&gt;Proc&lt;/strong&gt; (&lt;code&gt;on_entry Proc.new {puts 'entering sales mode'}&lt;/code&gt;), it will be called within the context of the &lt;code&gt;context&lt;/code&gt;.  Proc actions are also nice for quick and dirty actions.  They can accept parameters and are preferred to String actions, unless you want to marshal your statemachine.  Using one Proc actions will prevent the entire statemachine from being marhsal-able.&lt;/p&gt;

&lt;h3&gt;Execution&lt;/h3&gt;

&lt;p&gt;For kicks let&amp;#8217;s put this statemachine thought a few events.&lt;/p&gt;

&lt;pre&gt;vending_machine.dollar
vending_machine.dollar
vending_machine.selection "Peanuts"&lt;/pre&gt;

&lt;p&gt;Here&amp;#8217;s the output:&lt;/p&gt;

&lt;pre&gt;going into operation mode
activating
refuding dollar
releasing product: Peanuts
going into sales mode&lt;/pre&gt;

&lt;p&gt;That sums it up for actions.  Next, we&amp;#8217;ll talk about how do deal with conditional login in your statemachine.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.8thlight.com/articles/2007/02/13/understanding-statemachines-part-3-conditional-logic"&gt;Understanding Statemachines, Part 3: Conditional Logic&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 30 Nov 2006 04:20:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:32fa4095-dee0-4c09-ae56-a0dcb85ef842</guid>
      <author>Micah</author>
      <link>http://blog.8thlight.com/articles/2006/11/30/understanding-statemachines-part-2-actions</link>
      <category>Coding</category>
      <category>Statemachine</category>
      <category>Micah</category>
      <enclosure type="image/png" length="14732" url="http://blog.8thlight.com/files/vending_machine2.png"/>
    </item>
    <item>
      <title>"Understanding Statemachines, Part 2: Actions" by jewellery</title>
      <description>&lt;p&gt;Well, I&amp;#8217;m not sure if this really provides a full UNDERSTANDING of Statemachines (like, what they are, and what that definition means) but I think (as a newbie) that I&amp;#8217;m understanding a little of where you&amp;#8217;re going with this. It may be a little more clear if I take a stab at it anyway as well as take a read of part two. Maybe part two will put things in better context for me so I&amp;#8217;ll have a broader understanding.&lt;/p&gt;</description>
      <pubDate>Tue, 22 Jul 2008 15:52:05 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:df706af5-a9ad-4022-bb8d-9eecbaf56f72</guid>
      <link>http://blog.8thlight.com/articles/2006/11/30/understanding-statemachines-part-2-actions#comment-798</link>
    </item>
    <item>
      <title>"Understanding Statemachines, Part 2: Actions" by proxy site</title>
      <description>&lt;p&gt;Thank you for  Understanding Statemachines, Part 2.&lt;/p&gt;

&lt;p&gt;this article is very helpful.&lt;/p&gt;</description>
      <pubDate>Sun, 16 Dec 2007 15:44:25 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:37563257-ec5a-4ec7-b39f-7fc5c8a2abc1</guid>
      <link>http://blog.8thlight.com/articles/2006/11/30/understanding-statemachines-part-2-actions#comment-461</link>
    </item>
    <item>
      <title>"Understanding Statemachines, Part 2: Actions" by luc</title>
      <description>&lt;p&gt;After executing the example above I got:&lt;/p&gt;

&lt;p&gt;going into sales mode  &amp;lt;&amp;#8212; wrong message!
going into operation mode
activating&lt;/p&gt;

&lt;p&gt;refuding dollar&lt;/p&gt;

&lt;p&gt;releasing product: Peanuts
going into sales mode&lt;/p&gt;

&lt;p&gt;It seems he always executes the on_entry message.&lt;/p&gt;</description>
      <pubDate>Sat, 15 Dec 2007 16:51:11 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:06db414e-eaeb-40d3-90a0-7e7b736dfab0</guid>
      <link>http://blog.8thlight.com/articles/2006/11/30/understanding-statemachines-part-2-actions#comment-459</link>
    </item>
  </channel>
</rss>
