<?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/"
	>

<channel>
	<title>Khelll&#039;s Blog &#187; DSL</title>
	<atom:link href="http://khelll.com/blog/tag/dsl/feed/" rel="self" type="application/rss+xml" />
	<link>http://khelll.com/blog</link>
	<description>Cool Web Development...</description>
	<lastBuildDate>Thu, 13 Oct 2011 03:48:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Ruby and Internal DSLs</title>
		<link>http://khelll.com/blog/ruby/ruby-and-internal-dsls/</link>
		<comments>http://khelll.com/blog/ruby/ruby-and-internal-dsls/#comments</comments>
		<pubDate>Tue, 30 Dec 2008 18:51:42 +0000</pubDate>
		<dc:creator>khelll</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[DSL]]></category>
		<category><![CDATA[Internal DSL]]></category>

		<guid isPermaLink="false">http://www.khelll.com/blog/?p=194</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://khelll.com/blog/ruby/ruby-and-internal-dsls/' addthis:title='Ruby and Internal DSLs '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>A Domain-specific language(DSL) is a computer language that&#8217;s targeted to a particular kind of problem, rather than a general purpose language that&#8217;s aimed at any kind of software problem. Domain specific languages have been talked about, and used for almost &#8230; <a href="http://khelll.com/blog/ruby/ruby-and-internal-dsls/">Continue reading <span class="meta-nav">&#8594;</span></a><div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://khelll.com/blog/ruby/ruby-and-internal-dsls/' addthis:title='Ruby and Internal DSLs' ><a class="addthis_button_twitter"></a><a class="addthis_button_facebook"></a><a class="addthis_button_email"></a><a class="addthis_button_print"></a><a class="addthis_button_compact"></a></div>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://khelll.com/blog/ruby/ruby-and-internal-dsls/' addthis:title='Ruby and Internal DSLs '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p><a href="http://www.martinfowler.com/bliki/DomainSpecificLanguage.html">A Domain-specific language(DSL)</a> is a computer language that&#8217;s targeted to a particular kind of problem, rather than a general purpose language that&#8217;s aimed at any kind of software problem. Domain specific languages have been talked about, and used for almost as long as computing has been done. Regular expressions and CSS are 2 examples of DSLs.</p>
<p>Any software language needs a parser and an interpreter(or compiler or a mix), but in DSLs, we have 2 types: external ones which need parsers and interpreters, and internal ones which rely on the hosting language power to give the feel of a particular language, and thus they don&#8217;t require their own parsers.</p>
<p>Ruby is a very convenient language for writing internal DSLs, it has several powerful techniques that enables you easily to write internal DSLs, and many famous products that we use are nothing but internal DSLs: <a href="http://haml.hamptoncatlin.com/">Haml</a>, <a href="http://builder.rubyforge.org/">Builder</a> and <a href="http://rake.rubyforge.org/">Rake </a>.</p>
<p>Lemme show you a very simple example on how an internal DSL might look like using ruby:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">RobotTasksExecuter.start do
  stack :boxes =&gt; 5 do
    fetch do
      rotate :rectangle =&gt; 60
      pick :speed =&gt; 'slow',:height =&gt; 15
      rotate :rectangle =&gt; -60
      free :speed =&gt; 'slow'
    end
    package do
      lock
      seal
    end
  end
end</pre></div></div>

<p>As you can tell, this is a very basic internal DSL, written to describe basic tasks for a robot.<br />
There is one task at the moment called &#8216;stack&#8217; where the robot should do 2 things: fetch the box, and then package it.<br />
Several ruby techniques are used to bring this basic DSL:<br />
1- Blocks: everything between &#8216;do .. end&#8217; keywords.<br />
2- Parenthesesless methods: like &#8216;lock&#8217; and &#8216;seal&#8217;.<br />
3- Passing hash values as method arguments without the need of using curly braces: like doing &#8216;pick :speed => &#8216;slow&#8217;,:height => 15&#8242;.</p>
<p>Now all i need is a simple functionality to execute this simple internal DSL:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># A dummy task class</span>
<span style="color:#9966CC; font-weight:bold;">class</span> RobotTask
  <span style="color:#008000; font-style:italic;"># A dummy run task</span>
  <span style="color:#008000; font-style:italic;"># type of task, a margin to indent the output, and some other attributes are passed</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> run<span style="color:#006600; font-weight:bold;">&#40;</span>type,margin,attrs=<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    output = <span style="color:#996600;">&quot;#{margin} Running task '#{type}'&quot;</span>
    output<span style="color:#006600; font-weight:bold;">+</span>=<span style="color:#996600;">&quot;, with attributes:&quot;</span> <span style="color:#9966CC; font-weight:bold;">if</span> !attrs.<span style="color:#9900CC;">empty</span>?
    <span style="color:#CC0066; font-weight:bold;">puts</span> output
    attrs.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>key,value<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{margin} --#{key} = #{value}&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># A simple tasks executer </span>
<span style="color:#008000; font-style:italic;"># This code is very basic and could be far optimized</span>
<span style="color:#9966CC; font-weight:bold;">class</span> RobotTasksExecuter
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;   **** Robot is working now ****&quot;</span>
    <span style="color:#008000; font-style:italic;"># This is used to indent the output</span>
    <span style="color:#0066ff; font-weight:bold;">@margin</span> = <span style="color:#996600;">&quot;&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Start the executer work</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">start</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># Instantiate an executer object and evaluate the DSL code block</span>
    new.<span style="color:#9900CC;">instance_eval</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;">#  All undefined methods will call method_missing</span>
  <span style="color:#008000; font-style:italic;">#  Let's use 'execute' as an alias for method_missing</span>
  <span style="color:#9966CC; font-weight:bold;">alias</span> method_missing execute
&nbsp;
  <span style="color:#008000; font-style:italic;"># All undefined methods will call this method, because of the aliasing taking place over.</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> execute<span style="color:#006600; font-weight:bold;">&#40;</span>type,attrs=<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@margin</span> <span style="color:#006600; font-weight:bold;">+</span>= <span style="color:#996600;">&quot;  &quot;</span>
    RobotTask.<span style="color:#9900CC;">new</span>.<span style="color:#9900CC;">run</span><span style="color:#006600; font-weight:bold;">&#40;</span>type,@margin,attrs<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">yield</span> <span style="color:#9966CC; font-weight:bold;">if</span> block_given?
    <span style="color:#0066ff; font-weight:bold;">@margin</span> = <span style="color:#0066ff; font-weight:bold;">@margin</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>,@margin.<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
RobotTasksExecuter.<span style="color:#9900CC;">start</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  stack <span style="color:#ff3333; font-weight:bold;">:boxes</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">5</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    fetch <span style="color:#9966CC; font-weight:bold;">do</span>
      rotate <span style="color:#ff3333; font-weight:bold;">:rectangle</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">60</span>
      pick <span style="color:#ff3333; font-weight:bold;">:speed</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'slow'</span>,:height <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">15</span>
      rotate <span style="color:#ff3333; font-weight:bold;">:rectangle</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">60</span>
      free <span style="color:#ff3333; font-weight:bold;">:speed</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'slow'</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    package <span style="color:#9966CC; font-weight:bold;">do</span>
      lock
      seal
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And the output:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">   **** Robot is working now ****
   Running task 'stack', with attributes:
   --boxes = 5
     Running task 'fetch'
       Running task 'rotate', with attributes:
       --rectangle = 60
       Running task 'pick', with attributes:
       --speed = slow
       --height = 15
       Running task 'rotate', with attributes:
       --rectangle = -60
       Running task 'free', with attributes:
       --speed = slow
     Running task 'package'
       Running task 'lock'
       Running task 'seal'</pre></div></div>

<p>In addition to the 3 points we mentioned earlier, another 2 ones should be added, as they are the heart of the above executer:</p>
<p>4- Reflection techniques: the one we used inside the class method &#8216;start&#8217;, exactly this line &#8220;new.instance_eval(&#038;block)&#8221;.<br />
5- method_missing: all undefined methods are received by &#8216;execute&#8217;, the alias of method_missing.</p>
<p>As i mentioned earlier, this is a very basic internal DSL, if you are looking for an advanced article covering a more advanced one, then don&#8217;t hesitate to check this <a href="http://www.codecommit.com/blog/ruby/xmlbuilder-a-ruby-dsl-case-study"> rich one</a> by Daniel Spiewak.</p>
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://khelll.com/blog/ruby/ruby-and-internal-dsls/' addthis:title='Ruby and Internal DSLs' ><a class="addthis_button_twitter"></a><a class="addthis_button_facebook"></a><a class="addthis_button_email"></a><a class="addthis_button_print"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://khelll.com/blog/ruby/ruby-and-internal-dsls/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

