<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>processi</title>
	<atom:link href="http://jmettraux.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://jmettraux.wordpress.com</link>
	<description>about processes and engines</description>
	<lastBuildDate>Mon, 06 Jul 2009 07:48:44 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<image>
		<url>http://www.gravatar.com/blavatar/9bb51c7af8944bbbd925e4c759d5d471?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>processi</title>
		<link>http://jmettraux.wordpress.com</link>
	</image>
			<item>
		<title>state machine != workflow engine</title>
		<link>http://jmettraux.wordpress.com/2009/07/03/state-machine-workflow-engine/</link>
		<comments>http://jmettraux.wordpress.com/2009/07/03/state-machine-workflow-engine/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 14:48:04 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[openwferu]]></category>
		<category><![CDATA[rules]]></category>
		<category><![CDATA[ruote]]></category>
		<category><![CDATA[state machine]]></category>
		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1238</guid>
		<description><![CDATA[This post is intended for Ruby developers. The idea for it came after numerous discussions with fellow programmers about state machines and workflow engines. 
What motivates me for posting is the publication of the 3rd issue of the excellent Rails Magazine. It contains an article named &#8220;Workflow solutions with AASM&#8221;.
At first a word of warning, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1238&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This post is intended for Ruby developers. The idea for it came after numerous discussions with fellow programmers about state machines and workflow engines. </p>
<p>What motivates me for posting is the publication of the <a href="http://railsmagazine.com/issues/3">3rd issue</a> of the excellent Rails Magazine. It contains an article named &#8220;Workflow solutions with AASM&#8221;.</p>
<p>At first a word of warning, I wrote these lines with no intention of minimizing the potential of state machines vs workflow engines. I&#8217;m listing workflow engine and state machine implementations for Ruby at the end of this post.</p>
<p>There are a number of open questions in this post, I don&#8217;t intend to answer them now or later. There are so many different use cases in the wild.</p>
<p><strong>spark</strong></p>
<p>The article &#8220;Workflow solutions with AASM&#8221; starts with :</p>
<blockquote><p>
There are two main forms of workflows: sequential and<br />
state-machine. Sequential workflows are predictable. They<br />
utilize the rules and conditions we provide at the beginning<br />
to progress a process forward. The workflow is in control of<br />
the process.</p>
<p>A state-machine workflow is the reverse. It is driven by<br />
external events to its completion. We define the states and<br />
required transitions between those states. The workflow sits<br />
and waits for an external event to occur before transitioning<br />
to one of the defined states. The decision making process hap-<br />
pens externally outside of the workflow – there is a structure<br />
to be followed still like a sequential workflow but control is<br />
passed to its external environment.
</p></blockquote>
<p>I&#8217;m <a href="http://openwferu.rubyforge.org">clearly</a> in the &#8220;sequential workflow&#8221; faction. But I refute the &#8217;sequential&#8217; label. Most of the state/transitions set out there can be qualified as &#8220;sequential&#8221;. Any workflow engine, in order to present any interest to its users, has to implement a certain number of <a href="http://workflowpatterns.com/patterns/control/index.php">[control flow] workflow patterns</a>. The number 1 control-flow pattern is named <a href="http://workflowpatterns.com/patterns/control/basic/wcp1.php">Sequence</a>, granted. But if you take a look at the pattern that immediately follows, it&#8217;s <a href="http://workflowpatterns.com/patterns/control/basic/wcp2.php">Parallel Split</a>. I can&#8217;t adhere to the &#8220;sequential workflow&#8221;  appellation.</p>
<p>Note that most workflow engines (you can call then &#8220;sequential workflow&#8221; engines) <a href="http://workflowpatterns.com/documentation/index.php">strive to implement</a> a large set of those control-flow patterns. This is usually done via their &#8216;process definition&#8217; language. The goal is to let users express their scenarii / pattern in a not too verbose way. We can argue that state machines may implement any of the control-flow patterns, my guess is &#8216;yes&#8217;, but what&#8217;s the cost in code ?</p>
<p>The difference between &#8220;sequential workflows&#8221; and &#8220;state machines&#8221; seems to lie not in the predictability of the former, but rather in how the flow between activities or state is weaved, especially how/where it&#8217;s concentrated.</p>
<p>Are &#8220;sequential workflows&#8221; and &#8220;state machines&#8221; excluding one another ?</p>
<p>The article states &#8220;sequential workflow are predictable. They utilize the rules and conditions we provide at the beginning&#8221;. It&#8217;s the same for state machines. The vast majority of [Ruby] state machine implementations rely on behaviour specified at implementation time (or right before the application&#8217;s [re]start).</p>
<p>The second paragraph I quoted up here says that &#8220;decision making process happens externally outside of the workflow (&#8230;) control is passed to its external environment&#8221;. I argue that a &#8220;sequential workflow&#8221; engine should do the same. A workflow [engine] can&#8217;t take a decision by itself, this task is usually handled by a human or a dedicated algorithm (a piece of code, a rule engine, a coin tossing engine wired to internet, whatever).</p>
<p><strong>case</strong></p>
<p>Wait, we&#8217;ve been using this &#8216;workflow&#8217; term quite liberally until now, what is it about ? Why do state machines seem to be the perfect vessel for it, at least in the eyes of the hard-working developer ?</p>
<p>Let&#8217;s look at how state machines are sold, at their use cases. Here is a classical example from a [Rails-oriented] state machine <a href="http://github.com/davidlee/state-fu/">library</a> :</p>
<pre name="code" class="ruby">

  class Document &lt; ActiveRecord::Base
    include StateFu

    def update_rss
      puts &quot;new feed!&quot;
      # ... do something here
    end

    machine( :status ) do
      state :draft do
        event :publish, :to =&gt; :published
      end

      state :published do
        on_entry :update_rss
        requires :author  # a database column
      end

      event :delete, :from =&gt; :ALL, :to =&gt; :deleted do
        execute :destroy
      end
    end
  end
</pre>
<p>It attaches behaviour (state and transitions) to a resource. If you look at the example of any Ruby state machine library out there, you will see this pattern : a set of states and transitions attached to a resource in the system (a Model).</p>
<p>Let&#8217;s move to an adjacent example, it&#8217;s also about a document, but it&#8217;s in the &#8220;sequential workflow&#8221; faction (<a href="http://openwferu.rubyforge.org">ruote</a>). (The &#8216;cursor&#8217; expression in the process definition allows for the flow to be rewound or skipped&#8230;) :</p>
<pre name="code" class="ruby">

Ruote.process_definition :name =&gt; &#039;doc review&#039;, revision =&gt; &#039;0.2&#039; do

  cursor do

    participant &#039;${f:author}&#039;, :step =&gt; &#039;finalize document&#039;
    participant &#039;${f:review_team}&#039;, :step =&gt; &#039;review document&#039;

    rewind :unless =&gt; &#039;${f:approved}&#039;

    concurrence do
      participant &#039;${f:publisher}&#039;, :step =&gt; &#039;publish document&#039;
      participant &#039;${f:author}&#039;, :step =&gt; &#039;publication notification&#039;
    end
  end
end
</pre>
<p>There is a document yes, but it could be a folder of documents. The process definition is a separate thing, meant to be turned into multiple process instances.</p>
<p>Workflow engines are mostly process definitions interpreters, graduating as &#8220;operating systems for business processes&#8221; (think &#8216;ps&#8217; and &#8216;kill dash 9&#8242; but with business processes / process instances).</p>
<p>As said, most of the Ruby state machine libraries out there are all about binding behaviour to resources / models. What about moving to the workflow engine camp and instead of binding to a system artefact (document, order, invoice, book, customer, &#8230;) why not attach state and transitions to a virtual artefact, a so-called &#8220;process instance&#8221; ? The state machine would move out of its shell and turn into a full workflow engine. Or is that so ?</p>
<p><strong>cases</strong></p>
<p>Back to the 90% of the cases : the state machine attached to a model. What if there is more than 1 &#8220;stateable&#8221; model ? Easy. But what if transition in model A provokes a transition in model B ? The &#8220;real workflow&#8221; now lies at the intersection of two models.</p>
<p>The workflow engine will expose a process definition while, with the state machines, we&#8217;ll have to extract it from two or more models. Another advantage of workflow engines is that they have process definition versioning. Most of them run process instances from process definition X at version 2 happily with process instances from version 4, concurrently.</p>
<p>On the other hand, when a process instance goes ballistic it might take some time to repair it (align it with the reality of the business process). It might be easier with state machines, a simple SQL update usually, but what if there are multiple inter-related behaviours ? Pain on both sides.</p>
<p>Whatever the tool, you&#8217;ll have to carefully avoid locking yourself into your private hell of a system.</p>
<p><strong>nuances</strong></p>
<p>Kenneth Kalmer <a href="http://www.opensourcery.co.za/2009/07/06/driving-business-processes-in-ruby/">is using</a> a mix of <a href="http://github.com/pluginaweek/state_machine/">state_machine</a> and <a href="http://openwferu.rubyforge.org">ruote</a> in their <a href="http://www.ispinabox.co.za/">ISP in a box</a> product. The state machine library is in charge of the state of its various models while the workflow engine does the orchestration. &#8220;Processes that drives the provision of services&#8221;</p>
<p>The two techniques may co-exist. Tinier states / transitions sets, more concise process definitions. Models managing their states, process instances coordinating the states of multiple models.</p>
<p>It&#8217;s OK to remove the workflow engine and replace it with a &#8220;super&#8221; state machine, but then you&#8217;re entering in the real workflow territory and the <a href="http://workflowpatterns.com">mindset</a> is a bit different and at that level, you&#8217;ll be exposed to a flavour of change that directly involves your customer / end-user. Nowhere to hide.</p>
<p><strong>machines</strong></p>
<p>I&#8217;ve been linking profusely to my <a href="http://openwferu.rubyforge.org">ruote</a> workflow engine. The only other workflow engine I&#8217;ve spotted in the wild is <a href="http://rubyforge.org/projects/rbpm/">rbpm</a>, but its development stopped a long time ago.</p>
<p>Here is a non-exhaustive list of Ruby state machine implementations, in no specific order :</p>
<ul>
<li><a href="http://github.com/davidlee/state-fu/">state-fu</a></li>
<li><a href="http://github.com/pluginaweek/state_machine/">state_machine</a></li>
<li><a href="http://github.com/rubyist/aasm/tree/master">acts_as_state_machine</a></li>
<li><a href="http://github.com/ryan-allen/workflow/">ryan-allen&#8217;s workflow</a></li>
<li><a href="http://github.com/geekq/workflow/">geekq&#8217;s workflow</a> (fork of the previous)</li>
<li><a href="http://github.com/binary42/remix-state/">remix-state</a></li>
<li><a href="http://github.com/avdi/alter-ego/">alter-ego</a></li>
<li><a href="http://github.com/jbarnette/stateful/">stateful</a></li>
<li><a href="http://github.com/bokmann/Stone-Path/">stone-path</a> (in extraction)</li>
<li><a href="http://github.com/hashrocket/automatic-acts-as-state-machine/">automatic-acts-as-state-machine</a></li>
<li>&#8230;</li>
</ul>
<p>There&#8217;s a plethora of state machines versus very few (one or two) workflow engines. This could be interpreted in multiple ways.</p>
<p>State machines follow a well defined <a href="http://en.wikipedia.org/wiki/State_pattern">pattern</a>, while workflow engines have to follow a <a href="http://workflowpatterns.com">set of patterns</a>, and workflow engines strive to be &#8220;operating systems for business processes&#8221;. State machines are more humble.</p>
<p>So Rails Magazine #3 is <a href="http://railsmagazine.com/issues/3">out</a>. Great read.</p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1238/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1238&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/07/03/state-machine-workflow-engine/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>
	</item>
		<item>
		<title>rufus-tokyo 0.1.13</title>
		<link>http://jmettraux.wordpress.com/2009/06/02/rufus-tokyo-0-1-13/</link>
		<comments>http://jmettraux.wordpress.com/2009/06/02/rufus-tokyo-0-1-13/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 00:47:40 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[ffi]]></category>
		<category><![CDATA[jruby]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>
		<category><![CDATA[tokyocabinet]]></category>
		<category><![CDATA[tokyotyrant]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1218</guid>
		<description><![CDATA[With the initial releases of rufus-tokyo, I happily cut corners and went with C strings (ending with NUL).
This isn&#8217;t optimal, often you need to store binary data as the value, the resulting &#8217;string&#8217; contains NUL characters and values get truncated at restitution. I was working around that with Base64 encoding. Fine, the perf cost isn&#8217;t [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1218&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://www.flickr.com/photos/stevemettraux/3562217297"><img src="http://jmettraux.files.wordpress.com/2009/06/shinjuku.jpg?w=250&#038;h=178" alt="shinjuku" title="shinjuku" width="250" height="178" class="alignleft size-full wp-image-1223" style="border:0;" /></a>With the <a href="http://jmettraux.wordpress.com/2009/01/23/ruby-ffi-tokyo-cabinet/">initial releases</a> of rufus-tokyo, I happily cut corners and went with <a href="http://en.wikipedia.org/wiki/C_string">C strings</a> (ending with NUL).</p>
<p>This isn&#8217;t optimal, often you need to store binary data as the value, the resulting &#8217;string&#8217; contains NUL characters and values get truncated at restitution. I was working around that with Base64 encoding. Fine, the perf cost isn&#8217;t too heavy. But then, binary data was working fine on the Rufus::Edo side (wrapping the original tokyo{cabinet|tyrant}-ruby), why should Rufus::Tokyo be an exception ?</p>
<p>rufus-tokyo 0.1.13 which just got released fixes that issue.</p>
<p>Thanks to <a href="http://www.benmabey.com/">Ben Mabey</a> for pointing out the issue.</p>
<p><a href="http://blog.bitfluent.com/">Kamal Fariz Mahyuddin</a> was kind enough to fork rufus-tokyo and add the #putkeep(k, v) method which only put if there was no previous value associated with the key. The collaboration with Kamal also prompted me to provide #add_int and #add_double for int/double counters in cabinet/tyrant.</p>
<p><a href="http://github.com/jmettraux/rufus-tokyo">http://github.com/jmettraux/rufus-tokyo</a></p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1218/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1218&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/06/02/rufus-tokyo-0-1-13/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/06/shinjuku.jpg" medium="image">
			<media:title type="html">shinjuku</media:title>
		</media:content>
	</item>
		<item>
		<title>rufus-scheduler 2.0, with em flavour</title>
		<link>http://jmettraux.wordpress.com/2009/05/07/rufus-scheduler-20-with-em-flavour/</link>
		<comments>http://jmettraux.wordpress.com/2009/05/07/rufus-scheduler-20-with-em-flavour/#comments</comments>
		<pubDate>Thu, 07 May 2009 02:27:36 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>
		<category><![CDATA[scheduling]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1194</guid>
		<description><![CDATA[This blog is turning into a release gallery.
Anyway. Just released rufus-scheduler 2.0. It&#8217;s a complete rewrite. The only new &#8220;feature&#8221; is an EventMachine mode.
The plain scheduler uses a thread waking up every 0.330s (by default) to check for jobs to trigger, while the em-based scheduler uses an EventMachine timer.
Other flavour for the core loop are [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1194&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://github.com/jmettraux/rufus-scheduler/"><img src="http://jmettraux.files.wordpress.com/2009/05/jlc1.png?w=150&#038;h=225" title="swiss made" width="150" height="225" border="0" class="alignleft size-full wp-image-1196" style="border:0;padding-right:5px;"></a>This blog is turning into a release gallery.</p>
<p>Anyway. Just released <a href="http://github.com/jmettraux/rufus-scheduler/">rufus-scheduler</a> 2.0. It&#8217;s a complete rewrite. The only new &#8220;feature&#8221; is an <a href="http://www.rubyeventmachine.com/">EventMachine</a> mode.</p>
<p>The plain scheduler uses a thread waking up every 0.330s (by default) to check for jobs to trigger, while the em-based scheduler uses an EventMachine timer.</p>
<p>Other flavour for the core loop are possible, why not something 1.9 fiber based in the short term ?</p>
<p>This release 2.0 is mostly backward compatible. Only some corner cases and advanced usages (block arity) have changed (they have been simplified). Having a look at the <a href="http://github.com/jmettraux/rufus-scheduler/blob/master/README.rdoc">readme</a> should help.</p>
<pre name="code" class="ruby">

require &#039;rubygems&#039;
require &#039;rufus/scheduler&#039; # sudo gem install rufus-scheduler

s = Rufus::Scheduler.start_new
</pre>
<p>will still work, it will return an instance of Rufus::Scheduler::PlainScheduler, but if an EM reactor is running, it will stick to it and return a Rufus::Scheduler::EmScheduler instance.</p>
<p>source : <a href="http://github.com/jmettraux/rufus-scheduler/">http://github.com/jmettraux/rufus-scheduler/</a><br />
rdoc : <a href="http://rufus.rubyforge.org/rufus-scheduler/">http://rufus.rubyforge.org/rufus-scheduler/</a><br />
ml : <a href="http://groups.google.com/group/rufus-ruby">http://groups.google.com/group/rufus-ruby</a></p>
<p>Many thanks to <a href="http://github.com/kjwierenga">Klaas Jan Wierenga</a> for contributing nice stress tests (for the 1.0 and the 2.0 branches), thanks as well to <a href="http://github.com/kennethkalmer">Kenneth Kalmer</a> for its <a href="http://www.opensourcery.co.za/2009/04/28/easy-ruby-cronjobs-with-daemon-kit/">daemon-kit + rufus-scheduler</a> effort.</p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1194/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1194/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1194/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1194/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1194/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1194&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/05/07/rufus-scheduler-20-with-em-flavour/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/05/jlc1.png" medium="image">
			<media:title type="html">swiss made</media:title>
		</media:content>
	</item>
		<item>
		<title>rufus-decision 1.1, ruby decision tables</title>
		<link>http://jmettraux.wordpress.com/2009/04/25/rufus-decision-11-ruby-decision-tables/</link>
		<comments>http://jmettraux.wordpress.com/2009/04/25/rufus-decision-11-ruby-decision-tables/#comments</comments>
		<pubDate>Sat, 25 Apr 2009 14:19:50 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[decision]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>
		<category><![CDATA[rules]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1136</guid>
		<description><![CDATA[rufus-decision is a small ruby gem for &#8216;running decision tables&#8217;. Decision tables are useful for mapping conditions to actions.
This example decision table considers two conditions : &#8216;topic&#8217; and &#8216;region&#8217; (I tend to call them &#8216;inputs&#8217;). Certain combinations of condition  yield one or more output value.
In the example, when the topic is about finance and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1136&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://github.com/jmettraux/rufus-decision/">rufus-decision</a> is a small ruby gem for &#8216;running decision tables&#8217;. <a href="http://en.wikipedia.org/wiki/Decision_table">Decision tables</a> are useful for mapping conditions to actions.</p>
<p><img src="http://jmettraux.files.wordpress.com/2009/04/decision_table_0.png?w=263&#038;h=180" alt="which reporter for which event" title="decision_table_0" width="263" height="180" class="size-full wp-image-1141" style="border:0;" align="left" />This example decision table considers two conditions : &#8216;topic&#8217; and &#8216;region&#8217; (I tend to call them &#8216;inputs&#8217;). Certain combinations of condition  yield one or more output value.</p>
<p>In the example, when the topic is about finance and the region is Europe, the team member Donald gets selected.</p>
<p>This is a vanilla decision table, as soon as a &#8216;match&#8217; is found, the run is over, an output value has been found.</p>
<p>Note that the arrangement of rules, their order, does matter. Ernest who is in charge of finance for the rest of the world, comes after America and Europe, Charly and Donald respectively. If Ernest were placed before them, all the input sets with the topic set to &#8216;finance&#8217; would go to him, ignoring his two colleagues.</p>
<p>Likewise, our &#8216;handle all the rest&#8217; Zach has been placed last, collecting all the input sets that didn&#8217;t match.</p>
<p>It&#8217;s easy to reproduce the table with some code :</p>
<pre name="code" class="ruby">

if topic == &#039;sports&#039;
  if region == &#039;europe&#039;
    team_member = &#039;Alice&#039;
  else
    team_member = &#039;Bob&#039;
  end
elsif topic == &#039;finance&#039;
  # ...
elsif topic == &#039;politics&#039;
  # ...
else
  team_member = &#039;Zach&#039;
end
</pre>
<p>Turning business logic into code is a common task for software developers, but what about simply &#8216;running&#8217; a decision table directly ?</p>
<p>Decision tables are easy to edit with spreadsheet software and that&#8217;s a happy coincidence since many domain experts are Excel jockeys (see <a href="http://martinfowler.com/bliki/LayProgrammer.html">lay programmer</a>).</p>
<p>Excel isn&#8217;t the only spreadsheet software, see for example our decision table in <a href="http://spreadsheets.google.com/pub?key=rs4Z_1gjtyfgXupxXz_nAYw">Google Spreadsheet</a>.</p>
<p>At this point, I have to say I&#8217;m sorry, I won&#8217;t suggest any mean to run decision tables directly inside of Excel, I will bring back the flow to the Ruby environment, with some code triggering our business logic.</p>
<pre name="code" class="ruby">

require &#039;rubygems&#039;
require &#039;rufus/decision&#039; # sudo gem install rufus-decision

table = %{
  in:topic,in:region,out:team_member
  sports,europe,Alice
  sports,,Bob
  finance,america,Charly
  finance,europe,Donald
  finance,,Ernest
  politics,asia,Fujio
  politics,america,Gilbert
  politics,,Henry
  ,,Zach
}

table = Rufus::Decision::Table.new(table)

p table.run(&#039;topic&#039; =&gt; &#039;politics&#039;, &#039;region&#039; =&gt; &#039;america&#039;)
  # =&gt; {&quot;region&quot;=&gt;&quot;america&quot;, &quot;topic&quot;=&gt;&quot;politics&quot;, &quot;team_member&quot;=&gt;&quot;Gilbert&quot;}

p table.run(&#039;topic&#039; =&gt; &#039;sports&#039;, &#039;region&#039; =&gt; &#039;antarctic&#039;)
  # =&gt; {&quot;region&quot;=&gt;&quot;antarctic&quot;, &quot;topic&quot;=&gt;&quot;sports&quot;, &quot;team_member&quot;=&gt;&quot;Bob&quot;}

p table.run(&#039;topic&#039; =&gt; &#039;culture&#039;, &#039;region&#039; =&gt; &#039;america&#039;)
  # =&gt; {&quot;region&quot;=&gt;&quot;america&quot;, &quot;topic&quot;=&gt;&quot;culture&quot;, &quot;team_member&quot;=&gt;&quot;Zach&quot;}
</pre>
<p>rufus-decision understands decision tables with rules expressed per column as well as per row :</p>
<pre name="code" class="ruby">

table = %{
  in:topic,sports,sports,finance,finance,finance,politics,politics,politics,
  in:region,europe,,america,europe,,asia,america,,
  out:team_member,Alice,Bob,Charly,Donald,Ernest,Fujio,Gilbert,Henry,Zach
}
</pre>
<p>The parameter to Rufus::Decision::Table.new() can be a CSV string, an array of arrays, the path to a CSV file or the URI of a CSV file. With a Google spreadsheet [published] table, our example could be cut to :</p>
<pre name="code" class="ruby">

require &#039;rubygems&#039;
require &#039;rufus/decision&#039; # sudo gem install rufus-decision

table = Rufus::Decision::Table.new(
  &#039;http://spreadsheets.google.com/pub?key=rs4Z_1gjtyfgXupxXz_nAYw&amp;output=csv&#039;)

# ...
</pre>
<p>So far so good, our domain expert may publish decision tables on the company information&#8217;s system and we can use them directly. But what to do when the number of conditions and rules get large ?</p>
<p>A programmer is expected to test his code, he&#8217;s even expected to deliver code with tests. A sane programmer can&#8217;t live without tests. Lay programmers should welcome testing as well.</p>
<p>rufus-decision comes with a &#8220;rufus_decide&#8221; command line tool for running decision tables in batch.</p>
<p>Given this input file (topics_in.csv), where the first row lists the keys and the next rows hold the values :</p>
<pre style="margin-left:1em;margin-bottom:1em;">
topic,region
sports,america
politics,europe
culture,
politics,africa
</pre>
<p>the decision table can be exercised with :</p>
<pre style="margin-left:1em;margin-bottom:1em;">
rufus_decide \
-t "http://spreadsheets.google.com/pub?key=rs4Z_1gjtyfgXupxXz_nAYw&amp;output=csv" \
-i topics_in.csv
</pre>
<p>which will yield :</p>
<pre style="margin-left:1em;margin-bottom:1em;">
region,team_member,topic
america,Bob,sports
europe,Henry,politics
,Zach,culture
africa,Henry,politics
</pre>
<p>&#8216;rufus_decide&#8217; ran the decision table for each row in the input data and generated an output table with one row for each input row.</p>
<p>This &#8216;ideal&#8217; output can saved in a &#8216;goal.csv&#8217; file and used to &#8216;test&#8217; the decision table :</p>
<pre style="margin-left:1em;margin-bottom:1em;">
rufus_decide \
-t "http://spreadsheets.google.com/pub?key=rs4Z_1gjtyfgXupxXz_nAYw&amp;output=csv" \
-i topics_in.csv \
-g goal.csv
</pre>
<p>Running rufus_decide with a goal will emit an output similar to the one of classical unit test tools.</p>
<p>This was an introduction to rufus-decision, whose version 1.1.0 was just released.</p>
<p><a href="http://jmettraux.files.wordpress.com/2009/04/web_decision.png"><img src="http://jmettraux.files.wordpress.com/2009/04/web_decision.png?w=150&#038;h=85" alt="web_decision" title="web_decision" width="150" height="85" class="alignleft size-thumbnail wp-image-1189" style="border:0;" /></a>The new release contains some kind of web-based <a href="http://github.com/jmettraux/rufus-decision/tree/master/demo">environment</a> for testing rules (see thumbnail on left), but well, I&#8217;m not quite convinced it&#8217;s useful.</p>
<p>source : <a href="http://github.com/jmettraux/rufus-decision/">http://github.com/jmettraux/rufus-decision/</a><br />
rdoc : <a href="http://rufus.rubyforge.org/rufus-decision/">http://rufus.rubyforge.org/rufus-decision/</a></p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1136/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1136&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/04/25/rufus-decision-11-ruby-decision-tables/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/04/decision_table_0.png" medium="image">
			<media:title type="html">decision_table_0</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/04/web_decision.png?w=150" medium="image">
			<media:title type="html">web_decision</media:title>
		</media:content>
	</item>
		<item>
		<title>rufus-tokyo 0.1.12, ext(lua)</title>
		<link>http://jmettraux.wordpress.com/2009/04/07/rufus-tokyo-0112-extlua/</link>
		<comments>http://jmettraux.wordpress.com/2009/04/07/rufus-tokyo-0112-extlua/#comments</comments>
		<pubDate>Tue, 07 Apr 2009 05:32:16 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[ffi]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>
		<category><![CDATA[tokyocabinet]]></category>
		<category><![CDATA[tokyotyrant]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1107</guid>
		<description><![CDATA[Just released version 0.1.12 of rufus-tokyo, a Ruby library for accessing Tokyo Cabinet and Tokyo Tyrant (via FFI or via the Ruby classes provided with the Tokyo products).
Tokyo Tyrant, once successfully compiled with &#8211;enable-lua, is open to lots of interesting usages.
In his last post on the Mixi dev blog, the author of Tokyo Cabinet / [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1107&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img src="http://jmettraux.files.wordpress.com/2009/04/tokyo-lua.gif?w=128&#038;h=128" alt="tokyo-lua" title="tokyo-lua" width="128" height="128" class="alignleft size-full wp-image-1109" style="border:0;" />Just released version 0.1.12 of <a href="http://github.com/jmettraux/rufus-tokyo/">rufus-tokyo</a>, a Ruby library for accessing Tokyo Cabinet and Tokyo Tyrant (via FFI or via the Ruby classes provided with the Tokyo products).</p>
<p>Tokyo Tyrant, once successfully compiled with &#8211;enable-lua, is open to lots of interesting usages.</p>
<p>In his <a href="http://alpha.mixi.co.jp/blog/?p=566">last post</a> on the Mixi dev blog, the author of Tokyo Cabinet / Tyrant is exposing his ideas about an application of map/reduce leveraging Tokyo Tyrant (post in Japanese, machine translation <a href="http://66.249.89.132/translate_c?hl=de&amp;ie=UTF-8&amp;sl=ja&amp;tl=en&amp;u=http://alpha.mixi.co.jp/blog/%3Fp%3D566&amp;prev=_t&amp;usg=ALkJrhjVlBOtWhgsMt5chQmIwZL0oF5EPg">here</a>). This demonstration relies on the embedded Lua runtime for the mapper/reducer implementation.</p>
<p>For this post, I&#8217;ll just show the vanilla &#8220;incr&#8221; function found in the Tokyo Tyrant <a href="http://tokyocabinet.sourceforge.net/tyrantdoc/#luaext">documentation</a> :</p>
<pre name="code" class="javascript">

--
-- incr.lua
--
function incr (key, i)
  i = tonumber(i)
  if not i then
    return nil
  end
  local old = tonumber(_get(key))
  if old then
    i = old + i
  end
  if not _put(key, i) then
    return nil
  end
  return i
end
</pre>
<p>This Lua function increments the current value bound for a key by a given amount.</p>
<p>You start your Lua-enabled Tokyo Tyrant with something like :</p>
<pre>
  ttserver -ext incr.lua test.tch
&nbsp;
</pre>
<p>and then hit it with code like :</p>
<pre name="code" class="ruby">

# test.rb

require &#039;rubygems&#039;
require &#039;rufus/tokyo/tyrant&#039; # sudo gem install rufus-tokyo

t = Rufus::Tokyo::Tyrant.new(&#039;127.0.0.1&#039;, 1978)

5.times do
  puts t.ext(:incr, &#039;my-counter&#039;, 2).to_i
end

t.close
</pre>
<p>The &#8220;ext&#8221; method is available with the latest release of <a href="http://github.com/jmettraux/rufus-tokyo/">rufus-tokyo</a>, for the Rufus::Tokyo::Tyrant and Rufus::Edo::NetTyrant classes.</p>
<p>I updated my documentation about <a href="http://openwferu.rubyforge.org/tokyo.html">Tokyo Cabinet / Tyrant install</a> with some &#8211;enable-lua information.</p>
<p>This release of rufus-tokyo also adds transaction support for the Rufus::Tokyo::Cabinet class (requires Tokyo Cabinet 1.4.13).</p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1107/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1107&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/04/07/rufus-tokyo-0112-extlua/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/04/tokyo-lua.gif" medium="image">
			<media:title type="html">tokyo-lua</media:title>
		</media:content>
	</item>
		<item>
		<title>gem freeze</title>
		<link>http://jmettraux.wordpress.com/2009/03/30/gem-freeze/</link>
		<comments>http://jmettraux.wordpress.com/2009/03/30/gem-freeze/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 08:18:07 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1092</guid>
		<description><![CDATA[This doesn&#8217;t deserve a gem. It&#8217;s just a plain file, so it&#8217;s packaged as a gist. It&#8217;s inspired by Rails&#8217; rake rails:freeze:gems but I made it for my non-rails stuff.


jmettraux@sanma ~/tmp/test $ ruby frigo.rb dm-migrations
 . created dir vendor
 .. from http://gems.rubyforge.org/ got dm-migrations-0.9.10
 .. from http://gems.rubyforge.org/ got dm-core-0.9.10
 .. from http://gems.rubyforge.org/ got data_objects-0.9.11
 .. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1092&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This doesn&#8217;t deserve a gem. It&#8217;s just a plain file, so it&#8217;s packaged as <a href="http://gist.github.com/87639">a gist</a>. It&#8217;s inspired by Rails&#8217; <a href="http://www.softiesonrails.com/2008/1/3/freezing-your-rails-application">rake rails:freeze:gems</a> but I made it for my non-rails stuff.</p>
<pre>

jmettraux@sanma ~/tmp/test $ ruby frigo.rb dm-migrations
 . created dir vendor
 .. from http://gems.rubyforge.org/ got dm-migrations-0.9.10
 .. from http://gems.rubyforge.org/ got dm-core-0.9.10
 .. from http://gems.rubyforge.org/ got data_objects-0.9.11
 .. from http://gems.rubyforge.org/ got addressable-2.0.2
 .. from http://gems.rubyforge.org/ got rake-0.8.4
 .. from http://gems.rubyforge.org/ got rspec-1.2.2
 .. from http://gems.rubyforge.org/ got cucumber-0.2.2
 .. from http://gems.rubyforge.org/ got term-ansicolor-1.0.3
 .. from http://gems.rubyforge.org/ got treetop-1.2.5
 .. from http://gems.rubyforge.org/ got polyglot-0.2.5
 .. from http://gems.rubyforge.org/ got hoe-1.11.0
 .. from http://gems.rubyforge.org/ got rubyforge-1.0.3
 .. from http://gems.rubyforge.org/ got diff-lcs-1.1.2
 .. from http://gems.rubyforge.org/ got builder-2.1.2
 .. from http://gems.rubyforge.org/ got launchy-0.3.3
 .. from http://gems.rubyforge.org/ got configuration-0.0.5
 .. from http://gems.rubyforge.org/ got extlib-0.9.10

jmettraux@sanma ~/tmp/test $ ls vendor/
addressable-2.0.2       dm-core-0.9.10          polyglot-0.2.5
builder-2.1.2           dm-migrations-0.9.10    rake-0.8.4
configuration-0.0.5     extlib-0.9.10           rspec-1.2.2
cucumber-0.2.2          frozen.rb               rubyforge-1.0.3
data_objects-0.9.11     hoe-1.11.0              term-ansicolor-1.0.3
diff-lcs-1.1.2          launchy-0.3.3           treetop-1.2.5
</pre>
<p>&nbsp;</p>
<p>OK, it downloaded dm-migrations and all its required gems under vendor/ but what is this vendor/frozen.rb thing ?</p>
<pre name="code" class="ruby">

# require this file to get all the frozen/unpacked gems into the load path
#
# ( created via frigo.rb  http://gist.github.com/87639 )

here = File.expand_path(File.dirname(__FILE__))

Dir.entries(here).select { |p|
  p.match(/^[^\.]/) and File.directory?(&quot;#{here}/#{p}/lib&quot;)
}.each { |p|
  $:.unshift(&quot;#{here}/#{p}/lib&quot;)
}
</pre>
<p>&#8220;require &#8216;vendor/frozen.rb&#8217;&#8221; will add to the loadpath all the lib/ paths under the vendor/ dir. This frozen.rb file is added by the frigo.rb freezer.</p>
<p>frigo.rb is [awaiting obsolescence] at <a href="http://gist.github.com/87639">http://gist.github.com/87639</a></p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1092/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1092/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1092/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1092/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1092/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1092/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1092/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1092/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1092/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1092/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1092&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/03/30/gem-freeze/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>
	</item>
		<item>
		<title>rufus-lua 1.0 out</title>
		<link>http://jmettraux.wordpress.com/2009/03/27/rufus-lua-10-out/</link>
		<comments>http://jmettraux.wordpress.com/2009/03/27/rufus-lua-10-out/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 06:26:39 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[lua]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1079</guid>
		<description><![CDATA[Just released rufus-lua 1.0
There are two main new features : lua garbage collection control (thanks Alain) and the possibility to bind Ruby blocks as Lua functions.
Rufus-lua is available via
sudo gem install rufus-lua
&#160;
       <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1079&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://www.lua.org/"><img src="http://jmettraux.files.wordpress.com/2009/03/logo1.gif?w=128&#038;h=128" alt="lua" title="lua" width="128" height="128" class="alignleft size-full wp-image-1078" style="border:0;" /></a>Just released <a href="http://github.com/jmettraux/rufus-lua/">rufus-lua</a> 1.0</p>
<p>There are two main new features : lua garbage collection control (thanks <a href="http://blogs.law.harvard.edu/hoanga/">Alain</a>) and the possibility to <a href="http://github.com/jmettraux/rufus-lua/blob/e0af4fe0d2198aa9e7423e891491956f8922d902/README.txt#L52-69">bind Ruby blocks as Lua functions</a>.</p>
<p>Rufus-lua is available via
<pre style="background-color:#f3f3f3;display:inline;">sudo gem install rufus-lua</pre>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1079/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1079/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1079/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1079/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1079/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1079/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1079/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1079/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1079/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1079/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1079&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/03/27/rufus-lua-10-out/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/03/logo1.gif" medium="image">
			<media:title type="html">lua</media:title>
		</media:content>
	</item>
		<item>
		<title>rufus-tokyo 0.1.10, limit(count, offset)</title>
		<link>http://jmettraux.wordpress.com/2009/03/19/rufus-tokyo-0110/</link>
		<comments>http://jmettraux.wordpress.com/2009/03/19/rufus-tokyo-0110/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 05:50:34 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[ffi]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>
		<category><![CDATA[tokyocabinet]]></category>
		<category><![CDATA[tokyotyrant]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1053</guid>
		<description><![CDATA[Just released rufus-tokyo 0.1.10. It supports the new setlimit method in Tokyo Cabinet 1.4.10 tables and Tokyo Tyrant 1.1.17 tables.
(I put up a piece of documentation on how to install TC and TT at http://openwferu.rubyforge.org/tokyo.html)
What&#8217;s the deal with this setlimit method ? Well, it&#8217;s an improvement over setmax which only accepted a count parameter.


require &#039;rubygems&#039;
require [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1053&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://www.tokyometro.jp/anshin/kaiteki/poster/manner_200807.html"><img src="http://jmettraux.files.wordpress.com/2009/03/music.gif?w=110&#038;h=111" alt="music" title="music" width="110" height="111" class="alignleft size-full wp-image-1055" style="border:0;" /></a>Just released rufus-tokyo 0.1.10. It supports the new setlimit method in Tokyo Cabinet 1.4.10 tables and Tokyo Tyrant 1.1.17 tables.</p>
<p>(I put up a piece of documentation on how to install TC and TT at <a href="http://openwferu.rubyforge.org/tokyo.html">http://openwferu.rubyforge.org/tokyo.html</a>)</p>
<p>What&#8217;s the deal with this setlimit method ? Well, it&#8217;s an improvement over setmax which only accepted a count parameter.</p>
<pre name="code" class="ruby">

require &#039;rubygems&#039;
require &#039;rufus/tokyo&#039;

t = Rufus::Tokyo::Table.new(&#039;table.tct&#039;)

t[&#039;pk0&#039;] = { &#039;name&#039; =&gt; &#039;alfred&#039;, &#039;age&#039; =&gt; &#039;22&#039; }
t[&#039;pk1&#039;] = { &#039;name&#039; =&gt; &#039;bob&#039;, &#039;age&#039; =&gt; &#039;18&#039; }
t[&#039;pk2&#039;] = { &#039;name&#039; =&gt; &#039;charly&#039;, &#039;age&#039; =&gt; &#039;45&#039; }
t[&#039;pk3&#039;] = { &#039;name&#039; =&gt; &#039;doug&#039;, &#039;age&#039; =&gt; &#039;77&#039; }
t[&#039;pk4&#039;] = { &#039;name&#039; =&gt; &#039;ephrem&#039;, &#039;age&#039; =&gt; &#039;32&#039; }

p t.query { |q|
  q.order_by &#039;age&#039;
  q.limit(2, 3) # 2 records max, skip 3 records
}
  # =&gt; [ {&quot;name&quot;=&gt;&quot;ephrem&quot;, :pk=&gt;&quot;pk4&quot;, &quot;age&quot;=&gt;&quot;32&quot;},
  #      {&quot;name&quot;=&gt;&quot;charly&quot;, :pk=&gt;&quot;pk2&quot;, &quot;age&quot;=&gt;&quot;45&quot;} ]

t.close
</pre>
<p>(Oops, I <a href="http://gist.github.com/81608">noticed</a> the max/count parameter is not always respected, submitted a bug report&#8230; And not sure if this offset/skip is &#8216;pagination&#8217; out of the box, it seems more like a &#8217;skip&#8217;, literally)</p>
<p>This release of rufus-tokyo supports previous versions of Tokyo Cabinet and Tokyo Tyrant as well.</p>
<p>sudo gem install rufus-tokyo or <a href="http://github.com/jmettraux/rufus-tokyo/">http://github.com/jmettraux/rufus-tokyo/</a></p>
<p>Many thanks to <a href="http://github.com/byu">Benjamin Yu</a> for pointing out the issue.</p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1053/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1053/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1053/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1053/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1053/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1053/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1053/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1053/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1053/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1053/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1053&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/03/19/rufus-tokyo-0110/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/03/music.gif" medium="image">
			<media:title type="html">music</media:title>
		</media:content>
	</item>
		<item>
		<title>ruote 0.9.20</title>
		<link>http://jmettraux.wordpress.com/2009/03/18/ruote-0920/</link>
		<comments>http://jmettraux.wordpress.com/2009/03/18/ruote-0920/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 07:59:52 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[bpm]]></category>
		<category><![CDATA[openwferu]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruote]]></category>
		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1038</guid>
		<description><![CDATA[I just released ruote 0.9.20. The original release text is on github, but I&#8217;m reproducing it here, with more details.
This release is not backward compatible. Changing the engine and restarting with a batch of persisted processes will not work. Start with new processes or migrate them.
Speaking of persistence, this release features revised and new persistence [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1038&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://openwferu.rubyforge.org/"><img src="http://jmettraux.files.wordpress.com/2009/03/ruote.png?w=229&#038;h=88" alt="ruote" title="ruote" width="229" height="88" class="alignleft size-full wp-image-1041" style="border:0;"></a>I just released ruote 0.9.20. The original <a href="http://github.com/jmettraux/ruote/blob/5b166ce67bd6e003da6ec4ce28b733f1cd50d28d/RELEASE.txt">release text</a> is on github, but I&#8217;m reproducing it here, with more details.</p>
<p>This release is not backward compatible. Changing the engine and restarting with a batch of persisted processes will not work. Start with new processes or migrate them.</p>
<p>Speaking of persistence, this release features revised and new <a href="http://openwferu.rubyforge.org/persistence.html">persistence mechanisms</a>. The most common one, the one directly bound to the file system has been revised to use Ruby marshalling instead of YAML with a net performance increase. Tokyo Cabinet and Tokyo Tyrant persistence mechanisms have been added as well, along with a DataMapper one.</p>
<p>Should the need to move from one persistence mecha to the other arise, a <a href="http://openwferu.rubyforge.org/persistence.html#pooltool">pooltool.ru</a> has been included for easy migrations, back and forth.</p>
<p>On the front of expressions themselves, &#8217;sleep&#8217; and &#8216;wait&#8217; have been merged, as was pointed out to me, &#8220;wait &#8216;2d&#8217;&#8221; sounds more businessy than &#8220;sleep &#8216;2d&#8217;&#8221;.</p>
<p>Each expression may now have a <a href="http://openwferu.rubyforge.org/on_error.html">on_cancel and/or on_error attribute</a>, pointing to a subprocess or participant called in case of error or cancel respectively. This was suggested by Raphael Simon and <a href="http://opensourcery.co.za/">Kenneth Kalmer</a>.</p>
<p>There is a new way to define process via Ruby :</p>
<pre name="code" class="ruby">

  OpenWFE.process_definition :name =&gt; &#039;cfp&#039; do
    sequence do
      prepare_call
      concurrence do
        vendor1
        vendor2
        vendor3
      end
      decide_which
    end
  end
</pre>
<p>Kenneth Kalmer came up with a <a href="http://openwferu.rubyforge.org/participants.html#JabberParticipant">JabberParticipant</a> and a JabberListener and <a href="http://github.com/tosch">Torsten Schoenebaum</a> implemented an <a href="http://openwferu.rubyforge.org/participants.html#ActiveResourceParticipant">ActiveResourceParticipant</a> for modifying Rails resources from Ruote.</p>
<p>Many thanks to everybody who contributed code, feedback, ideas to Ruote !</p>
<p>Ruote&#8217;s source : <a href="http://github.com/jmettraux/ruote/">http://github.com/jmettraux/ruote/</a></p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1038/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1038/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1038/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1038/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1038/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1038/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1038/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1038/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1038/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1038/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1038&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/03/18/ruote-0920/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/03/ruote.png" medium="image">
			<media:title type="html">ruote</media:title>
		</media:content>
	</item>
		<item>
		<title>ruby to lua</title>
		<link>http://jmettraux.wordpress.com/2009/03/16/ruby-to-lua/</link>
		<comments>http://jmettraux.wordpress.com/2009/03/16/ruby-to-lua/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 09:39:34 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[ffi]]></category>
		<category><![CDATA[jruby]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=999</guid>
		<description><![CDATA[With the help from Alain I just released rufus-lua 0.1.0.
This ruby gem talks to Lua via Ruby FFI. One could say it&#8217;s &#8220;embedding Lua&#8221;, as Lua is described as &#8220;Lua is a powerful, fast, lightweight, embeddable scripting language.&#8221;
I feel tempted by Lua, there&#8217;s the speed, the austerity and that javascript feeling.
&#160;
Rufus-lua is not the first [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=999&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://www.lua.org/"><img src="http://jmettraux.files.wordpress.com/2009/03/lua.gif?w=102&#038;h=102" alt="lua" title="lua" width="102" height="102" class="alignleft size-full wp-image-1004" style="border:0;" /></a>With the help from <a href="http://blogs.law.harvard.edu/hoanga/">Alain</a> I just released <a href="http://github.com/jmettraux/rufus-lua/">rufus-lua 0.1.0</a>.</p>
<p>This ruby gem talks to <a href="http://www.lua.org">Lua</a> via Ruby FFI. One could say it&#8217;s &#8220;embedding Lua&#8221;, as Lua is <a href="http://www.lua.org/about.html">described</a> as &#8220;Lua is a powerful, fast, lightweight, embeddable scripting language.&#8221;</p>
<p>I feel tempted by Lua, there&#8217;s the speed, the austerity and that javascript feeling.</p>
<p>&nbsp;</p>
<p>Rufus-lua is not the first bridge between Lua and Ruby, there are also :</p>
<p>* <a href="http://rubyluabridge.rubyforge.org/">http://rubyluabridge.rubyforge.org/</a><br />
* <a href="http://raa.ruby-lang.org/project/ruby-lua">http://raa.ruby-lang.org/project/ruby-lua</a></p>
<p>They are worth a look, but I was a bit disappointed, they are not available via &#8217;sudo gem install &#8230;&#8217;.</p>
<p>Rufus-lua is available via Rubygems, but since it&#8217;s a FFI thing, it needs to talk to the dynamic library packaging of Lua. Well, it&#8217;s not available by default, there&#8217;s <a href="http://github.com/jmettraux/rufus-lua/blob/78245371b23234ffe41cf97756dd97b28f3eef01/README.txt#L51-72">some work involved</a> (but not too much).</p>
<p>Something great about FFI is that it works for Ruby 1.8.6, Ruby 1.9.1 and JRuby (1.1.6) (and will work soon for Rubinius, its original platform).</p>
<p>&nbsp;</p>
<p>Once liblua.dylib is on your system, along with rufus-lua (sudo gem install rufus-lua), you can play with code like :</p>
<pre name="code" class="ruby">

require &#039;rubygems&#039;
require &#039;rufus/lua&#039;

s = Rufus::Lua::State.new

t = s.eval(%{
  return { message = { &#039;hello&#039;, &#039;from&#039;, &#039;Lua&#039; },
    funk = function (x) return 2^x end }
})

p t[&#039;message&#039;].to_a # =&gt; [&quot;hello&quot;, &quot;from&quot;, &quot;lua&quot;]
p t[&#039;funk&#039;].call(8) # =&gt; 256.0

s.close
</pre>
<p>Well, it&#8217;s only a 0.1.0 release&#8230;</p>
<p>&nbsp;</p>
<p>As rufus-lua is using FFI it&#8217;s slower at the &#8220;frontier&#8221;, here is a naive benchmark for computing a Fibonacci suite, with Fiber (Ruby 1.9) and Coroutines on the Lua side :</p>
<pre name="code" class="ruby">

require &#039;benchmark&#039;
require &#039;rubygems&#039;
require &#039;rufus/lua&#039;

RUBYFIBS = Fiber.new do
  n1 = n2 = 1
  loop do
    Fiber.yield n1
    n1, n2 = n2, n1+n2
  end
end

s = %{
  co = coroutine.create(function ()
    local n1 = 1; local n2 = 1
    while true do
      coroutine.yield(n1)
      n1, n2 = n2, n1+n2
    end
  end)
  return co
}

LUA = Rufus::Lua::State.new
LUAFIBS = LUA.eval(s)

N = 10_000
Benchmark.benchmark(&#039; &#039; * 31 + Benchmark::Tms::CAPTION, 31) do |b|
  b.report(&#039;ruby&#039;) do
    N.times { RUBYFIBS.resume }
  end
  b.report(&#039;lua via ruby&#039;) do
    N.times { LUAFIBS.resume }
  end
  b.report(&#039;lua&#039;) do
    LUA.eval(&quot;for i = 0, #{N} do coroutine.resume(co) end&quot;)
  end
end

LUA.close
</pre>
<p>For the <a href="http://github.com/jmettraux/rufus-lua/blob/78245371b23234ffe41cf97756dd97b28f3eef01/test/bm_fiber.rb">original</a>. Running it on my board yields something along the lines of :</p>
<pre style="margin-top:19px;margin-bottom:19px;margin-left:14px;">
$ ruby19 test/bm_fiber.rb
                  user     system      total        real
ruby          0.050000   0.010000   0.060000 (  0.052032)
lua via ruby  0.180000   0.000000   0.180000 (  0.195411)
lua           0.010000   0.000000   0.010000 (  0.006394)
</pre>
<p>Well, nothing spectacular, that just states that it&#8217;s better to not cross the border too often : the &#8220;lua via ruby&#8221; bench has Ruby resuming the Lua coroutine 10_000 times and it&#8217;s costly.</p>
<p>&nbsp;</p>
<p>rufus-lua,<br />
on github : <a href="http://github.com/jmettraux/rufus-lua/">http://github.com/jmettraux/rufus-lua/</a><br />
rdoc : <a href="http://rufus.rubyforge.org/rufus-lua/">http://rufus.rubyforge.org/rufus-lua/</a><br />
the rest of rufus : <a href="http://rufus.rubyforge.org">http://rufus.rubyforge.org</a></p>
<p>lua : <a href="http://www.lua.org">http://www.lua.org</a><br />
ffi : <a href="http://kenai.com/projects/ruby-ffi/">http://kenai.com/projects/ruby-ffi/</a></p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/999/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/999/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/999/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/999/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/999/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/999/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/999/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/999/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/999/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/999/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=999&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/03/16/ruby-to-lua/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/03/lua.gif" medium="image">
			<media:title type="html">lua</media:title>
		</media:content>
	</item>
	</channel>
</rss>