<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Perpetually Curious]]></title>
  <link href="http://lambdafoo.com/atom.xml" rel="self"/>
  <link href="http://lambdafoo.com/"/>
  <updated>2012-09-18T22:12:40+10:00</updated>
  <id>http://lambdafoo.com/</id>
  <author>
    <name><![CDATA[Tim McGilchrist]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Getting started with Sinan]]></title>
    <link href="http://lambdafoo.com/blog/2012/09/10/sinan-intro/"/>
    <updated>2012-09-10T21:00:00+10:00</updated>
    <id>http://lambdafoo.com/blog/2012/09/10/sinan-intro</id>
    <content type="html"><![CDATA[<h2>Background</h2>

<p>When I started with Erlang I used a simple Makefile to call <code>erlc</code> and pretty
much did things by hand. After a number of years in the wilderness I found out
about <a href="http://github.com/basho/rebar">rebar</a> from Basho and started using that
to compile my code. Everything was good, rebar knew how to compile OTP apps and pull down external
dependencies. Except when I needed to generate releases. It&#8217;s
not necessarily straight forward to get rebar to build you a nice release,
<a href="http://www.metabrew.com/article/erlang-rebar-tutorial-generating-releases-upgrades">not that it&#8217;s impossible</a>
it&#8217;s just not as simple as I&#8217;d like.</p>

<p>Enter Sinan, the somewhat forgotten erlang build tool.</p>

<p>Sinan is a build tool designed to build Erlang/OTP projects, releases and
applications. It claims to be more OTP than rebar and uses the OTP metadata
artefacts to build your project with little configuration needed.</p>

<p>Let&#8217;s see how well it delivers on the promise.</p>

<h2>Sinan From Scratch</h2>

<p>First you&#8217;ll need Erlang installed, which your friendly local package management tool
should provide. I&#8217;m using Homebrew on OSX so I just did:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ brew install erlang
</span><span class='line'>...
</span><span class='line'>$ erl -v
</span><span class='line'>Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]
</span><span class='line'>
</span><span class='line'>Eshell V5.9.1  (abort with ^G)
</span><span class='line'>1></span></code></pre></td></tr></table></div></figure>


<p>Linux should be similarly straight forward and Windows well you&#8217;re on your own.</p>

<p>Grab sinan from the
<a href="https://github.com/erlware/sinan/downloads">downloads page</a> on github, I&#8217;m
using version 4.1.1. Put it somewhere on your PATH, I&#8217;ve got mine in ~/bin which is on my PATH, and chmod
+x it so it&#8217;s executable.</p>

<p>Now for the fun bit, type <code>sinan gen</code> and fill in the details.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Please specify your name
</span><span class='line'>your name> Tim McGilchrist
</span><span class='line'>Please specify your email address
</span><span class='line'>your email> timmcgil@gmail.com
</span><span class='line'>Please specify the copyright holder
</span><span class='line'>copyright holder ("Tim McGilchrist")>
</span><span class='line'>Please specify name of your project
</span><span class='line'>project name> sinan_demo
</span><span class='line'>Please specify version of your project
</span><span class='line'>project version> 0.0.1
</span><span class='line'>Please specify the ERTS version ("5.9.1")>
</span><span class='line'>Is this a single application project ("n")> y
</span><span class='line'>Would you like a build config? ("y")> y
</span><span class='line'>Project was created, you should be good to go!</span></code></pre></td></tr></table></div></figure>


<p>From that Sinan has generated a project, filling in your details, with an OTP
application and some build configuration. Your directories should look something
similar to this.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sinan_demo
</span><span class='line'>    ├── config
</span><span class='line'>    │   └── sys.config
</span><span class='line'>    ├── doc
</span><span class='line'>    ├── ebin
</span><span class='line'>    │   └── overview.edoc
</span><span class='line'>    ├── include
</span><span class='line'>    ├── sinan.config
</span><span class='line'>    └── src
</span><span class='line'>        ├── sinan_demo.app.src
</span><span class='line'>        ├── sinan_demo_app.erl
</span><span class='line'>        └── sinan_demo_sup.erl</span></code></pre></td></tr></table></div></figure>


<p>It includes all the standard directories you&#8217;d expect plus a <code>sinan.config</code>
file.</p>

<p>First a little diversion, we need to add a line to the sinan config file, which
tells sinan to include the erlang runtime system when it generates a release.
Open sinan.config and add <code>{include_erts, true}.</code> as the last line. It should
look like this:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='erlang'><span class='line'><span class="p">{</span><span class="n">project_name</span><span class="p">,</span> <span class="n">sinan_demo</span><span class="p">}.</span>
</span><span class='line'><span class="p">{</span><span class="n">project_vsn</span><span class="p">,</span> <span class="s">&quot;0.0.1&quot;</span><span class="p">}.</span>
</span><span class='line'>
</span><span class='line'><span class="p">{</span><span class="n">build_dir</span><span class="p">,</span>  <span class="s">&quot;_build&quot;</span><span class="p">}.</span>
</span><span class='line'>
</span><span class='line'><span class="p">{</span><span class="n">ignore_dirs</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;_&quot;</span><span class="p">,</span> <span class="s">&quot;.&quot;</span><span class="p">]}.</span>
</span><span class='line'>
</span><span class='line'><span class="p">{</span><span class="n">ignore_apps</span><span class="p">,</span> <span class="p">[]}.</span>
</span><span class='line'>
</span><span class='line'><span class="p">{</span><span class="n">include_erts</span><span class="p">,</span> <span class="n">true</span><span class="p">}.</span>
</span></code></pre></td></tr></table></div></figure>


<p>Back to making our generated code runnable.</p>

<p>By default the generated supervisor doesn&#8217;t point to a valid module so you&#8217;ll
need to remedy that before trying to startup the application. Create a new file
called <code>sinan_demo_server.erl</code> in <code>src</code> and drop the following code in.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
</pre></td><td class='code'><pre><code class='erlang'><span class='line'><span class="p">-</span><span class="ni">module</span><span class="p">(</span><span class="n">sinan_demo_server</span><span class="p">).</span>
</span><span class='line'>
</span><span class='line'><span class="p">-</span><span class="ni">behaviour</span><span class="p">(</span><span class="n">gen_server</span><span class="p">).</span>
</span><span class='line'>
</span><span class='line'><span class="c">%% API</span>
</span><span class='line'><span class="p">-</span><span class="ni">export</span><span class="p">([</span><span class="n">start_link</span><span class="o">/</span><span class="mi">0</span><span class="p">,</span> <span class="n">add_one</span><span class="o">/</span><span class="mi">0</span><span class="p">,</span> <span class="n">total</span><span class="o">/</span><span class="mi">0</span><span class="p">]).</span>
</span><span class='line'>
</span><span class='line'><span class="c">%% Callbacks</span>
</span><span class='line'><span class="p">-</span><span class="ni">export</span><span class="p">([</span><span class="n">init</span><span class="o">/</span><span class="mi">1</span><span class="p">,</span> <span class="n">handle_call</span><span class="o">/</span><span class="mi">3</span><span class="p">,</span> <span class="n">handle_cast</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="n">handle_info</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span>
</span><span class='line'>         <span class="n">terminate</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="n">code_change</span><span class="o">/</span><span class="mi">3</span><span class="p">]).</span>
</span><span class='line'>
</span><span class='line'><span class="p">-</span><span class="ni">record</span><span class="p">(</span><span class="nl">state</span><span class="p">,</span> <span class="p">{</span><span class="n">count</span><span class="p">}).</span>
</span><span class='line'>
</span><span class='line'><span class="c">%%%===================================================================</span>
</span><span class='line'><span class="c">%%% API functions</span>
</span><span class='line'><span class="c">%%%===================================================================</span>
</span><span class='line'>
</span><span class='line'><span class="nf">start_link</span><span class="p">()</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="nn">gen_server</span><span class="p">:</span><span class="n">start_link</span><span class="p">({</span><span class="n">local</span><span class="p">,</span> <span class="o">?</span><span class="nv">MODULE</span><span class="p">},</span> <span class="o">?</span><span class="nv">MODULE</span><span class="p">,</span> <span class="p">[],</span> <span class="p">[]).</span>
</span><span class='line'>
</span><span class='line'><span class="nf">total</span><span class="p">()</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="nn">gen_server</span><span class="p">:</span><span class="n">call</span><span class="p">(</span><span class="o">?</span><span class="nv">MODULE</span><span class="p">,</span> <span class="n">total</span><span class="p">).</span>
</span><span class='line'>
</span><span class='line'><span class="nf">add_one</span><span class="p">()</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="nn">gen_server</span><span class="p">:</span><span class="n">call</span><span class="p">(</span><span class="o">?</span><span class="nv">MODULE</span><span class="p">,</span> <span class="n">add</span><span class="p">).</span>
</span><span class='line'>
</span><span class='line'><span class="c">%%%===================================================================</span>
</span><span class='line'><span class="c">%%% Callbacks</span>
</span><span class='line'><span class="c">%%%===================================================================</span>
</span><span class='line'>
</span><span class='line'><span class="nf">init</span><span class="p">([])</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="nn">io</span><span class="p">:</span><span class="n">format</span><span class="p">(</span><span class="s">&quot;starting</span><span class="si">~n</span><span class="s">&quot;</span><span class="p">,</span> <span class="p">[]),</span>
</span><span class='line'>    <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nl">#state</span><span class="p">{</span><span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">},</span> <span class="mi">0</span><span class="p">}.</span>
</span><span class='line'>
</span><span class='line'><span class="nf">handle_call</span><span class="p">(</span><span class="n">add</span><span class="p">,</span> <span class="p">_</span><span class="nv">From</span><span class="p">,</span> <span class="nv">State</span><span class="p">)</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="nv">NewCount</span> <span class="o">=</span> <span class="nv">State</span><span class="nl">#state.count</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span>
</span><span class='line'>    <span class="nv">NewState</span> <span class="o">=</span> <span class="nv">State</span><span class="nl">#state</span><span class="p">{</span><span class="n">count</span> <span class="o">=</span> <span class="nv">NewCount</span><span class="p">},</span>
</span><span class='line'>    <span class="nv">Reply</span>    <span class="o">=</span> <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nv">NewState</span><span class="p">},</span>
</span><span class='line'>    <span class="p">{</span><span class="n">reply</span><span class="p">,</span> <span class="nv">Reply</span><span class="p">,</span> <span class="nv">NewState</span><span class="p">};</span>
</span><span class='line'><span class="nf">handle_call</span><span class="p">(</span><span class="n">total</span><span class="p">,</span> <span class="p">_</span><span class="nv">From</span><span class="p">,</span> <span class="nv">State</span> <span class="o">=</span> <span class="nl">#state</span><span class="p">{</span> <span class="n">count</span> <span class="o">=</span> <span class="nv">Count</span> <span class="p">})</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="p">{</span><span class="n">reply</span><span class="p">,</span> <span class="nv">Count</span><span class="p">,</span> <span class="nv">State</span><span class="p">};</span>
</span><span class='line'><span class="nf">handle_call</span><span class="p">(</span><span class="nv">Msg</span><span class="p">,</span> <span class="p">_</span><span class="nv">From</span><span class="p">,</span> <span class="nv">State</span><span class="p">)</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="p">{</span><span class="n">reply</span><span class="p">,</span> <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nv">Msg</span><span class="p">},</span> <span class="nv">State</span><span class="p">}.</span>
</span><span class='line'>
</span><span class='line'><span class="nf">handle_cast</span><span class="p">(_</span><span class="nv">Msg</span><span class="p">,</span> <span class="nv">State</span><span class="p">)</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="p">{</span><span class="n">noreply</span><span class="p">,</span> <span class="nv">State</span><span class="p">}.</span>
</span><span class='line'>
</span><span class='line'><span class="nf">handle_info</span><span class="p">(_</span><span class="nv">Info</span><span class="p">,</span> <span class="nv">State</span><span class="p">)</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="p">{</span><span class="n">noreply</span><span class="p">,</span> <span class="nv">State</span><span class="p">}.</span>
</span><span class='line'>
</span><span class='line'><span class="nf">terminate</span><span class="p">(_</span><span class="nv">Reason</span><span class="p">,</span> <span class="p">_</span><span class="nv">State</span><span class="p">)</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="n">ok</span><span class="p">.</span>
</span><span class='line'>
</span><span class='line'><span class="nf">code_change</span><span class="p">(_</span><span class="nv">OldVsn</span><span class="p">,</span> <span class="nv">State</span><span class="p">,</span> <span class="p">_</span><span class="nv">Extra</span><span class="p">)</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nv">State</span><span class="p">}.</span>
</span></code></pre></td></tr></table></div></figure>


<p>It&#8217;s a pretty standard OTP gen_server application with 2 API
methods. <code>add_one/0</code> adds 1 to the counter and <code>total/0</code> returns the value of the
counter. The record definition setups up the state record for this server with
just a <code>count</code> attribute. The 2 API functions use the <code>gen_server:call/2</code> method
to hit the OTP callback for <code>handle_call/3</code>.</p>

<p>Next we need to fix the supervisor so it starts the correct module. Change
<code>sinan_demo_sup.erl</code> so it looks like the code below:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class='erlang'><span class='line'><span class="nf">start_link</span><span class="p">()</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="nn">supervisor</span><span class="p">:</span><span class="n">start_link</span><span class="p">({</span><span class="n">local</span><span class="p">,</span> <span class="o">?</span><span class="nv">SERVER</span><span class="p">},</span> <span class="o">?</span><span class="nv">MODULE</span><span class="p">,</span> <span class="p">[]).</span>
</span><span class='line'>
</span><span class='line'><span class="c">%%%===================================================================</span>
</span><span class='line'><span class="c">%%% Supervisor callbacks</span>
</span><span class='line'><span class="c">%%%===================================================================</span>
</span><span class='line'>
</span><span class='line'><span class="c">%% @private</span>
</span><span class='line'><span class="p">-</span><span class="ni">spec</span> <span class="n">init</span><span class="p">(</span><span class="n">list</span><span class="p">())</span> <span class="o">-&gt;</span> <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="p">{</span><span class="nv">SupFlags</span><span class="p">::</span><span class="n">any</span><span class="p">(),</span> <span class="p">[</span><span class="nv">ChildSpec</span><span class="p">::</span><span class="n">any</span><span class="p">()]}}</span> <span class="p">|</span>
</span><span class='line'>                            <span class="n">ignore</span> <span class="p">|</span> <span class="p">{</span><span class="n">error</span><span class="p">,</span> <span class="nv">Reason</span><span class="p">::</span><span class="n">any</span><span class="p">()}.</span>
</span><span class='line'><span class="nf">init</span><span class="p">([])</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="nv">RestartStrategy</span> <span class="o">=</span> <span class="n">one_for_one</span><span class="p">,</span>
</span><span class='line'>    <span class="nv">MaxRestarts</span> <span class="o">=</span> <span class="mi">1000</span><span class="p">,</span>
</span><span class='line'>    <span class="nv">MaxSecondsBetweenRestarts</span> <span class="o">=</span> <span class="mi">3600</span><span class="p">,</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">SupFlags</span> <span class="o">=</span> <span class="p">{</span><span class="nv">RestartStrategy</span><span class="p">,</span> <span class="nv">MaxRestarts</span><span class="p">,</span> <span class="nv">MaxSecondsBetweenRestarts</span><span class="p">},</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">Restart</span> <span class="o">=</span> <span class="n">permanent</span><span class="p">,</span>
</span><span class='line'>    <span class="nv">Shutdown</span> <span class="o">=</span> <span class="mi">2000</span><span class="p">,</span>
</span><span class='line'>    <span class="nv">Type</span> <span class="o">=</span> <span class="n">worker</span><span class="p">,</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">AChild</span> <span class="o">=</span> <span class="p">{</span><span class="n">sinan_demo_server</span><span class="p">,</span> <span class="p">{</span><span class="n">sinan_demo_server</span><span class="p">,</span> <span class="n">start_link</span><span class="p">,</span> <span class="p">[]},</span>
</span><span class='line'>              <span class="nv">Restart</span><span class="p">,</span> <span class="nv">Shutdown</span><span class="p">,</span> <span class="nv">Type</span><span class="p">,</span> <span class="p">[</span><span class="n">sinan_demo_server</span><span class="p">]},</span>
</span><span class='line'>
</span><span class='line'>    <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="p">{</span><span class="nv">SupFlags</span><span class="p">,</span> <span class="p">[</span><span class="nv">AChild</span><span class="p">]}}.</span>
</span></code></pre></td></tr></table></div></figure>


<p>The 2 changes we have make is to <code>start_link/0</code> so we can call the server
directly, and fix the child spec so it starts our new module.</p>

<p>Now we need to add the sinan_demo_server module to <code>sinan_demo.app.src</code> so we
know about it when generating the OTP application. Just add it to the list of
modules like so:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='erlang'><span class='line'><span class="c">%% This is the application resource file (.app file) for the,</span>
</span><span class='line'><span class="c">%% application.</span>
</span><span class='line'><span class="p">{</span><span class="n">application</span><span class="p">,</span> <span class="n">sinan_demo</span><span class="p">,</span>
</span><span class='line'> <span class="p">[{</span><span class="n">description</span><span class="p">,</span> <span class="s">&quot;Sinan demo application.&quot;</span><span class="p">},</span>
</span><span class='line'>  <span class="p">{</span><span class="n">vsn</span><span class="p">,</span> <span class="s">&quot;0.0.1&quot;</span><span class="p">},</span>
</span><span class='line'>  <span class="p">{</span><span class="n">modules</span><span class="p">,</span> <span class="p">[</span><span class="n">sinan_demo_app</span><span class="p">,</span>
</span><span class='line'>             <span class="n">sinan_demo_sup</span><span class="p">,</span>
</span><span class='line'>             <span class="n">sinan_demo_server</span><span class="p">]},</span>
</span><span class='line'>  <span class="p">{</span><span class="n">registered</span><span class="p">,[</span><span class="n">sinan_demo_sup</span><span class="p">]},</span>
</span><span class='line'>  <span class="p">{</span><span class="n">applications</span><span class="p">,</span> <span class="p">[</span><span class="n">kernel</span><span class="p">,</span> <span class="n">stdlib</span><span class="p">]},</span>
</span><span class='line'>  <span class="p">{</span><span class="n">mod</span><span class="p">,</span> <span class="p">{</span><span class="n">sinan_demo_app</span><span class="p">,[]}},</span>
</span><span class='line'>  <span class="p">{</span><span class="n">start_phases</span><span class="p">,</span> <span class="p">[]}]}.</span>
</span></code></pre></td></tr></table></div></figure>


<p>Compile with <code>sinan build</code> and hopefully everything works.</p>

<p>From here you&#8217;ve got a few options to get your application running,
but the easiest is just to use the sinan shell and start your application from
there.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ sinan shell
</span><span class='line'>Eshell V5.9.1  (abort with ^G)
</span><span class='line'>1> application:which_applications().
</span><span class='line'>[{parsetools,"XLATETOOLS  CXC 138 xx","2.0.7"},
</span><span class='line'> {syntax_tools,"Syntax tools","1.6.8"},
</span><span class='line'> {compiler,"ERTS  CXC 138 10","4.8.1"},
</span><span class='line'> {getopt,"Command-line options parser for Erlang","0.4.2"},
</span><span class='line'> {erlware_commons,"Additional standard library for Erlang",
</span><span class='line'>                  "0.6.1"},
</span><span class='line'> {stdlib,"ERTS  CXC 138 10","1.18.1"},
</span><span class='line'> {kernel,"ERTS  CXC 138 10","2.15.1"}]
</span><span class='line'>2> application:start(sinan_demo).
</span><span class='line'>ok</span></code></pre></td></tr></table></div></figure>


<p>We&#8217;ve started a shell and checked what applications are started with
<code>application:which_applications()</code>. Now start the demo application with:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>3> application:start(sinan_demo).
</span><span class='line'>ok</span></code></pre></td></tr></table></div></figure>


<p>Now lets test that we can call the application.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>4> sinan_demo_server:add_one().
</span><span class='line'>{ok,{state,1}}
</span><span class='line'>5> sinan_demo_server:add_one().
</span><span class='line'>{ok,{state,2}}</span></code></pre></td></tr></table></div></figure>


<p>As you can see it&#8217;s calling the server and incrementing the call count.</p>

<p>The next step is to create a release, which is as simple as running <code>sinan release</code></p>

<p>Sinan has created a number of new directories under <code>_build</code></p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ tree -d _build/
</span><span class='line'>    _build/
</span><span class='line'>    `-- sinan_demo
</span><span class='line'>        |-- bin
</span><span class='line'>        |-- erts-5.9.1
</span><span class='line'>        |-- lib
</span><span class='line'>        |   |-- kernel-2.15.1
</span><span class='line'>        |   |-- sinan_demo-0.0.1
</span><span class='line'>        |   `-- stdlib-1.18.1
</span><span class='line'>        `-- releases
</span><span class='line'>            `-- 0.0.1</span></code></pre></td></tr></table></div></figure>


<p>The <code>bin</code> directory is still there from last time but now we have an erts, lib
and releases directories. erts is there because earlier we asked sinan to
include an erlang runtime, so you can copy everything under _build/sinan_demo to
another machine without erlang installed and run this application. The
limitation being that the CPU and OS needs to match the machine you&#8217;ve built
on. <code>lib</code> includes all the applications you asked sinan to include, they&#8217;ll
match what you have in your collective .app.src files. <code>releases</code> contains
configuration files specific to a particular release of the application.</p>

<p>Starting the release generated is as simple as</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ ./_build/sinan_demo/bin/sinan_demo
</span><span class='line'>Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]
</span><span class='line'>
</span><span class='line'>starting
</span><span class='line'>Eshell V5.9.1  (abort with ^G)
</span><span class='line'>1> application:which_applications().
</span><span class='line'> [{sinan_demo,"Sinan demo application.","0.0.1"},
</span><span class='line'>  {stdlib,"ERTS  CXC 138 10","1.18.1"},
</span><span class='line'>  {kernel,"ERTS  CXC 138 10","2.15.1"}]
</span><span class='line'>2></span></code></pre></td></tr></table></div></figure>


<p>We&#8217;ll leave it there for now, but if you&#8217;re curious like me you&#8217;ll probably have
a bunch of questions of where to take sinan next.</p>

<p>Next time I&#8217;m going to cover:</p>

<ul>
<li>Generating Version 2</li>
<li>Doing an OTP upgrade to Version 2</li>
<li>Downgrading to Version 1</li>
</ul>


<p>But if you&#8217;ve got other suggestions please leave them in the comments.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[WebMachine Talk]]></title>
    <link href="http://lambdafoo.com/blog/2012/04/12/webmachine-talk/"/>
    <updated>2012-04-12T12:44:00+10:00</updated>
    <id>http://lambdafoo.com/blog/2012/04/12/webmachine-talk</id>
    <content type="html"><![CDATA[<p>I finally posting my slides for the WebMachine talk I gave at
<a href="http://www.meetup.com/Sydney-Erlang-User-Group/events/49204512/">ErlSyd</a>.</p>

<p>The content was fairly general WebMachine and REST stuff, going into how to
setup, build and structure a WebMachine application.</p>

<p>I&#8217;m planning on putting together something more detailed in the future, as the
current WebMachine resources are rather spartan. The plan is to do an extended
series of posts or a github/ebook site ala <a href="http://learnyousomeerlang.com/">learnyousomeerlang</a>.</p>

<p>Again the slides are up on github @ <a href="https://github.com/tmcgilchrist/webmachine_talk/">github.com/tmcgilchrist/webmachine_talk/</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Riak, Ruby and Ripple Talk]]></title>
    <link href="http://lambdafoo.com/blog/2012/03/15/riak-ruby-ripple-talk/"/>
    <updated>2012-03-15T10:26:00+11:00</updated>
    <id>http://lambdafoo.com/blog/2012/03/15/riak-ruby-ripple-talk</id>
    <content type="html"><![CDATA[<p>I recently presented a talk to
<a href="http://www.rubyonrails.com.au/">RoRo Sydney</a>, the local Ruby UG, on
<em>Riak and Ripple</em>.</p>

<p>The content was more on the general side of things, with my purpose
being to introduce the core Riak ideas and give some Ruby code for interacting
with Riak.</p>

<p>The slides are up on github @
<a href="https://github.com/tmcgilchrist/riak_ripple_talk/">github.com/tmcgilchrist/riak_ripple_talk/</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git rebase workflow]]></title>
    <link href="http://lambdafoo.com/blog/2012/02/10/git-rebase-workflow/"/>
    <updated>2012-02-10T14:00:00+11:00</updated>
    <id>http://lambdafoo.com/blog/2012/02/10/git-rebase-workflow</id>
    <content type="html"><![CDATA[<p>New gist for using a rebase workflow with git.</p>

<p>Again probably not interesting to everyone but it gives the bare bones of what
you need to do.</p>

<div><script src='https://gist.github.com/1785908.js?file='></script>
<noscript><pre><code>### Checkout a new working branch ###
     git checkout -b &lt;branchname&gt;

### Make Changes ###

     git add
     git commit -m &quot;description of changes&quot;

### Sync with remote ###

     git checkout master
     git pull --rebase

### Update branch ###

     git checkout &lt;branchname&gt;
     git rebase master

### Push Changes ###

     git checkout master
     git merge &lt;branchname&gt;
     git push

### Squash Last N Commits ###

     git rebase --interactive HEAD~N

### Conflicts ###

1. Resolve conflict my looking at the files in question.
2. git add &lt;resolved files&gt;
3. git rebase --continue

### Git Flow ###

     git flow init                             # setup project to use git-flow

     git flow feature start &lt;feature_name&gt;     # creates a new feature branch called &lt;feature_name&gt;

     git flow feature finish &lt;feature_name&gt;    # merge feature back into develop branch

     git flow release start &lt;version&gt;          # merge develop to release

</code></pre></noscript></div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Thoughts on GNU Hurd]]></title>
    <link href="http://lambdafoo.com/blog/2012/02/01/thoughts-on-gnu-hurd/"/>
    <updated>2012-02-01T10:34:00+11:00</updated>
    <id>http://lambdafoo.com/blog/2012/02/01/thoughts-on-gnu-hurd</id>
    <content type="html"><![CDATA[<p>After reading a recent
<a href="http://news.ycombinator.com/item?id=1474941">article</a>
about GNU Hurd on hacker news I&#8217;m struck by the thought that GNUs development of Hurd
is a perfect example of a failed software project.</p>

<p>There was an initial great idea to build a
<a href="http://en.wikipedia.org/wiki/Microkernel">microkernel</a> based OS with all these
cool features. But what crippled the project was a combination of:</p>

<ul>
<li>constantly switching priorities and technology. How many different kernels
did they consider and start work on only to abandon work when something
better/shinier came along.</li>
<li>failure to focus on getting something working and out the door. Great teams ship software!</li>
<li>they didn&#8217;t capture a community around developing Hurd like Linux and BSD have.</li>
<li>seems like they followed the Big Design up front approach to software
development whilst Linux went for the more agile iterative approach. Thus
capturing all the positive feedback and momentum that comes with getting
customer input and alway having a working product.</li>
</ul>


<p>Despite all this the idea of a Hurd system is still attractive to many and
personally I look upon it with some nostalgia. I was completely obsessed by
operating systems and coding them around 2000.</p>

<p>I&#8217;d love to see a successful Hurd project running on something like L4. But
would such a system gain enough interest in the current open source
environment. If Hurd was available before Linux it seems like it would have
taken off and they could have rode the wave of open source enthusiasm. Now it
seems to me that the space is pretty full and a new os has little opportunity to
gain real market share. Surely Linux and *BSDs are good enough for people interested
in a Hurd system.</p>

<p>Anyway this is all irrelevant until they have something working that people can
run, even in a limited sense. Debian has a
<a href="http://www.debian.org/ports/hurd/">port</a> but it seems progress is slow.</p>

<p><strong>Why people dont consider gnu projects?</strong>
Poor public image, it doesn&#8217;t appear fun to work on gnu. Look at the buzz around
rails for how to manage your public image. Restrictive coding standards and
legal hassle.</p>

<p><a href="http://www.h-online.com/open/features/GNU-HURD-Altered-visions-and-lost-promise-1030942.html">Original link</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Site Update]]></title>
    <link href="http://lambdafoo.com/blog/2012/01/22/site-update/"/>
    <updated>2012-01-22T00:00:00+11:00</updated>
    <id>http://lambdafoo.com/blog/2012/01/22/site-update</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been rather lax in my updates of late so here is a new site and a status
update all rolled into 1.</p>

<p>So a few updates for those interested.</p>

<p>I attended both YOW! and Erlang Factory Lite in Brisbane late last year, and had an
absolute blast. Met lots of cool people and got inspired to do more this
year. The only downside is I have far too many things I want to do and only
limited time.</p>

<p>Went to the YOW! workshop <a href="http://yowaustralia.com.au/YOW2011/general/workshopDetails.html?eventId=3464">&#8220;REST in Practice: A Tutorial on Web-based Distributed
Systems&#8221;</a>
by Jim Webber, and got a great new perspective about RESTful architectures along
with some gentle ribbing about the deficiencies of Rails due to me being the
only Ruby/Rails guy in attendance.</p>

<p>Shout out to <a href="http://buffered.io/">OJ</a> for organising the
<a href="http://www.erlang-factory.com/conference/Brisbane2011">Erlang Factory Lite</a>. He&#8217;s
talking at Erlang Factory in San Francisco about Riak, so go along and say hi.</p>

<p>I&#8217;ve been wanting to update my blog for a while so I bought a domain name or two
and converted the site off Wordpress. For now it&#8217;s living on github pages and is
very much a work in progress. More updates and features to come.</p>

<p>Other than that I&#8217;ve been hard at work on a few Ruby and Erlang projects, and am
excited to be attending more Sydney user groups. This month I was at <a href="http://www.rubyonrails.com.au/">RoRo</a> and there is an Erlang group starting up next
month which I&#8217;ll be at.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git and Mercurial Workflow Gist]]></title>
    <link href="http://lambdafoo.com/blog/2011/10/08/git-and-mercurial-workflow-gist/"/>
    <updated>2011-10-08T00:00:00+11:00</updated>
    <id>http://lambdafoo.com/blog/2011/10/08/git-and-mercurial-workflow-gist</id>
    <content type="html"><![CDATA[<p>Just added some gist notes on my git and mercurial workflow.</p>

<p>Switching between the two does my head in sometimes.</p>

<p>Probably not that interesting for git or mercurial experts but just something to
jog my memory when I have to switch. I&#8217;ve got them taped to my desk right beside
my note book of Emacs keybindings.</p>

<p><a href="https://gist.github.com/1271705">Git &amp; Github Gist</a></p>

<p><a href="https://gist.github.com/1271716">Mercurial Gist</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[iPad and eBooks galore]]></title>
    <link href="http://lambdafoo.com/blog/2011/10/06/ipad-and-ebooks-galore/"/>
    <updated>2011-10-06T00:00:00+11:00</updated>
    <id>http://lambdafoo.com/blog/2011/10/06/ipad-and-ebooks-galore</id>
    <content type="html"><![CDATA[<p>Having recently caved and bought an iPad. It&#8217;s exceptionally good, much better
than I expected, it&#8217;s just I need to fight to get it back off my wife and/or
kids.</p>

<p>I&#8217;ve started changing over to using eBooks for all my new technical books, and
getting rid of paper copies. I doing that I found that 2 of my favourite
publishers offer eBook upgrades to paper books you&#8217;ve already bought.</p>

<p><a href="http://oreilly.com">O&#8217;Reilly</a> offers this:</p>

<address>&#8220;Upgrade to the electronic version of any print book you&#8217;ve registered at
 oreilly.com, for just $4.99. &#8221;</address>


<p>All you need to do is register an account with them.</p>

<p><a href="http://www.manning.com/about/ebooks.html">Manning</a> offers this:</p>

<address>&#8220;Free eBook With Every pBook! If you are an owner of a Manning pBook
you can get a free eBook at any time easily from your account.&#8221;</address>


<p>And <a href="http://pragprog.com/">The Pragmatic Programmers</a> offer something similar.</p>

<p>So out with the dead trees and in with the bits.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Agressive Emacs Spring Clean]]></title>
    <link href="http://lambdafoo.com/blog/2011/10/05/agressive-emacs-spring-clean/"/>
    <updated>2011-10-05T00:00:00+11:00</updated>
    <id>http://lambdafoo.com/blog/2011/10/05/agressive-emacs-spring-clean</id>
    <content type="html"><![CDATA[<p>A few weeks ago I mentioned that I was going to start using Emacs regularly for my Ruby/Rails development.</p>

<p>Well it turned into a rather deep dive into Emacs customisation and the results
so far are very pleasing. Something about starting from scratch is very
liberating and I&#8217;ve found the customisation process very easy this time. So far
I have Emacs 24 setup with ECB, Rinari, ELPA and a whole host of Ruby/Rails
modes on both OS X and Ubuntu Linux.</p>

<p>Everything is up on <a href="https://github.com/tmcgilchrist/.emacs.d">github</a>.</p>

<p>I&#8217;ve still got my old configuration files hanging around in personal-lisp, which
I will gradually migrate over. The top of that list is getting my Erlang mode
and Distel working again.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Emacs reboot]]></title>
    <link href="http://lambdafoo.com/blog/2011/08/12/emacs-reboot/"/>
    <updated>2011-08-12T00:00:00+10:00</updated>
    <id>http://lambdafoo.com/blog/2011/08/12/emacs-reboot</id>
    <content type="html"><![CDATA[<p>I&#8217;m trying out a little experiment for the next few week. I&#8217;ll be using Emacs as
my Ruby/Rails environment today and hopefully every few days until I&#8217;m really
rocking my emacs-fu. During the day I&#8217;ll note what I don&#8217;t know how to do or
doesn&#8217;t work the way I&#8217;d like, and try to find a solution for that the next time
I&#8217;m using Emacs.</p>

<p>I&#8217;ve been somewhat <em>meh</em> about IntelliJ/RubyMine for a bit. They&#8217;re both nice
enough but it feels like I&#8217;m only using them as a fancy editor and everything
else (git/rspec/cucumber/rails) gets run in a terminal. Plus a few things are
really annoying me, code completion kind of sucks, memory usage of the IDE is
quite high and the refactoring support is not what it should be.</p>

<p>I&#8217;ve started with a blank slate, forked the
<a href="https://github.com/tmcgilchrist/emacs-starter-kit">emacs-starter-kit</a> and so
far only customised the colour theme.</p>

<p>Here&#8217;s to more productive emacs sessions.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Setting up Oracle 10g XE with Rails 3]]></title>
    <link href="http://lambdafoo.com/blog/2011/07/25/setting-up-oracle-10g-xe-with-rails-3/"/>
    <updated>2011-07-25T00:00:00+10:00</updated>
    <id>http://lambdafoo.com/blog/2011/07/25/setting-up-oracle-10g-xe-with-rails-3</id>
    <content type="html"><![CDATA[<p>Just linking to a gist I created about setting up Ubuntu with Oracle 10g XE and Rails 3.</p>

<div><script src='https://gist.github.com/1103621.js?file='></script>
<noscript><pre><code>### Notes on Setting up Oracle 10g XE with Rails

Capturing my notes about setting up an Oracle 10g XE / Rails environment for development work.
Tested using the following versions, others may work as well:

1. Ubuntu 11.04
2. Ruby 1.9.2
3. Rails 3
4. Oracle 10 XE

### Get Oracle 10g XE

Oracle 10g Express Edition (XE) is a simplified version of Oracle 10g designed to get you up and running with development, without wasting your time installing the full server edition.

1. Go to [http://www.oracle.com/technetwork/database/express-edition/downloads/index.html](http://www.oracle.com/technetwork/database/express-edition/downloads/index.html)
2. Click on the link to &quot;Oracle Database 10g Express Edition for Linux x86&quot;
3. Choose the &quot;Oracle Database 10g Express Edition (Universal)&quot; Debian package
   (named something like oracle-xe-universal\_10.2.0.1-1.0\_i386.deb).
   NOTE: You may have to register to download the package.


Swap space, do you have enough? Oracle 10g requires 1Gb of swap, check how much you have before doing the install. 

    $ free
                 total       used       free     shared    buffers     cached
    Mem:       3095692    3034396      61296          0     757000    1244148
    -/+ buffers/cache:    1033248    2062444
    Swap:       262136      23416     238720
    $ cat /proc/swaps
    Filename                          Type      Size        Used       Priority
    /host/ubuntu/disks/swap.disk      file      262136      23416      -1

See [http://www.debian-administration.org/articles/550](http://www.debian-administration.org/articles/550) for the easiest way to add extra swap.

### Install Oracle XE

Install the Linux Async IO library, called either libaio or libaio1 depending on the Ubuntu version.

    $ sudo apt-get install -y libaio

Follow the [&quot;Installing Oracle Database XE Server&quot; setup instructions](http://download.oracle.com/docs/cd/B25329_01/doc/install.102/b25144/toc.htm#CIHHJEHF),
choosing the **defaults**. e.g.

    $ sudo dpkg -i Downloads/oracle-xe-universal_10.2.0.1-1.0_i386.deb
    $ sudo /etc/init.d/oracle-xe configure
    
    Oracle Database 10g Express Edition Configuration
    -------------------------------------------------
    This will configure on-boot properties of Oracle Database 10g Express 
    Edition.  The following questions will determine whether the database should 
    be starting upon system boot, the ports it will use, and the passwords that 
    will be used for database accounts.  Press &lt;Enter&gt; to accept the defaults. 
    Ctrl-C will abort.
    
    Specify the HTTP port that will be used for Oracle Application Express [8080]:8080
    
    Specify a port that will be used for the database listener [1521]:
    
    Specify a password to be used for database accounts.  Note that the same
    password will be used for SYS and SYSTEM.  Oracle recommends the use of 
    different passwords for each database account.  This can be done after 
    initial configuration: password
    Confirm the password: password
    
    Do you want Oracle Database 10g Express Edition to be started on boot (y/n) [y]:y

    Starting Oracle Net Listener...Done
    Configuring Database...Done
    Starting Oracle Database 10g Express Edition Instance...Done
    Installation Completed Successfully.
    To access the Database Home Page go to &quot;http://127.0.0.1:8080/apex&quot;

### Set the Oracle Database XE Server Environment Variables

Add the following to $HOME/.bashrc

    # Oracle server environment
    . /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.sh

and then source your .bashrc:

    $ source ~/.bashrc

If you see an error like this:

    /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/nls_lang.sh: 114: [[: not found

then edit nls_lang.sh

    $ sudo vi /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/nls_lang.sh

and change

    #!/bin/sh

to

    #!/bin/bash

and try to source .bashrc again

### Rails Setup

To connect active record to oracle you'll need the [oracle-enhanced](https://github.com/rsim/oracle-enhanced) driver.

     gem install ruby-oci8
     gem install activerecord-oracle_enhanced-adapter

Put these in your Gemfile and lock down to whatever version works. For reference I'm using ruby-oci8 2.0.4 and oracle_enhanced 1.3.1

Create the development and test databases in Oracle using SQL*Plus

    $ sqlplus SYS/password AS SYSDBA
    
    SQL&gt; GRANT CONNECT, RESOURCE TO app_development IDENTIFIED BY app_development_password;
    SQL&gt; ALTER USER app_development DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp;
    SQL&gt; GRANT CONNECT, RESOURCE TO app_test IDENTIFIED BY app_test_password;
    SQL&gt; ALTER USER app_test DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp;
    SQL&gt; EXIT


Setup database.yml to point to the new tables. eg

    development:
        adapter: oracle_enhanced
        database: app_development
        username: app_development
        password: app_development_password


### Rails / Oracle Gotchas

1. Oracle Enhanced gem doesn't implement rake db:drop or db:create, you'll need to roll your own solution. [https://github.com/rsim/oracle-enhanced/issues/18](https://github.com/rsim/oracle-enhanced/issues/18) 

2. Oracle 10g XE packages are for 32bit linux, so if you're running 64bit you may have to tell dpkg to --force-architecture or something similar. It has been working for me on 64bit but your mileage may vary.</code></pre></noscript></div>


<p>The Oracle gem works for most of the common cases but it&#8217;s quite clear that in
the Rails world it isn&#8217;t a first class citizen.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Rubinius Virtual Machine]]></title>
    <link href="http://lambdafoo.com/blog/2011/07/05/the-rubinius-virtual-machine/"/>
    <updated>2011-07-05T00:00:00+10:00</updated>
    <id>http://lambdafoo.com/blog/2011/07/05/the-rubinius-virtual-machine</id>
    <content type="html"><![CDATA[<p>Cool talk about the Rubinius Virtual Machine.</p>

<p><a href="http://vimeo.com/17380962">http://vimeo.com/17380962</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rails, ORA-000972 and you]]></title>
    <link href="http://lambdafoo.com/blog/2011/06/24/rails-ora-000972-and-you/"/>
    <updated>2011-06-24T00:00:00+10:00</updated>
    <id>http://lambdafoo.com/blog/2011/06/24/rails-ora-000972-and-you</id>
    <content type="html"><![CDATA[<p>Lately I&#8217;ve been running up against <em>&#8220;ORA-00972: identifier is too long&#8221;</em>, when
writing Rails migrations for Oracle. This particular error indicates that one of
your identifiers is longer than 32 characters which is the maximum length for
Oracle.</p>

<p>It&#8217;ll look something like this in your code:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">CreateLongTable</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Migration</span>
</span><span class='line'>  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">up</span>
</span><span class='line'>    <span class="n">create_table</span> <span class="ss">:long_table</span> <span class="k">do</span> <span class="o">|</span><span class="n">t</span><span class="o">|</span>
</span><span class='line'>      <span class="n">t</span><span class="o">.</span><span class="n">string</span> <span class="ss">:title</span>
</span><span class='line'>      <span class="n">t</span><span class="o">.</span><span class="n">references</span> <span class="ss">:someother_really_long_identifier</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>This migration will give you a foreign key id called
<strong>someother_really_long_identifier_id</strong> which is obviously too long for
Oracle. The solution is to use your own foreign key id name. In your migration
add a shorter reference.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">CreateLongTable</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Migration</span>
</span><span class='line'>  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">up</span>
</span><span class='line'>    <span class="n">create_table</span> <span class="ss">:long_table</span> <span class="k">do</span> <span class="o">|</span><span class="n">t</span><span class="o">|</span>
</span><span class='line'>      <span class="n">t</span><span class="o">.</span><span class="n">string</span> <span class="ss">:title</span>
</span><span class='line'>      <span class="n">t</span><span class="o">.</span><span class="n">references</span> <span class="ss">:short_name</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then in your model use the shorter foreign key name.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">LongTable</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:someother_really_long_identifier</span><span class="p">,</span>
</span><span class='line'>             <span class="ss">:class_name</span> <span class="o">=&gt;</span> <span class="s1">&#39;ClassName&#39;</span><span class="p">,</span>
</span><span class='line'>             <span class="ss">:foreign_key</span> <span class="o">=&gt;</span> <span class="s1">&#39;short_name_id&#39;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>And everything should be sweet, your model will use
<strong>someother_really_long_identifier</strong> and no-one need know that the table is
really using <strong>short_name_id</strong>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ubuntu Server update]]></title>
    <link href="http://lambdafoo.com/blog/2011/03/08/ubuntu-server-update/"/>
    <updated>2011-03-08T00:00:00+11:00</updated>
    <id>http://lambdafoo.com/blog/2011/03/08/ubuntu-server-update</id>
    <content type="html"><![CDATA[<p>I posted a while ago about switching to Ubtuntu for my home server.</p>

<p>I&#8217;ve got the basics up an running on my MacMini (artemis). Namely DHCP for the
home network, DNS primarily as a caching DNS server and WWW for hosting my
wordpress steup.</p>

<p>The setup of DHCP was easy enough. Followed the find documentation on the Ubuntu
site. Same story for a caching DNS.</p>

<p>Setup Apache/PHP/MySQL was a quick &#8216;sudo apt-get install php5-mysql&#8217; and I
installed Wordpress via subversion checkout. I&#8217;ve also installed BIND9 as a
caching DNS server.</p>

<p>Some services I&#8217;m not bothering to migrate:</p>

<ul>
<li>Subversion, I&#8217;ve switched to github and migrated anything I cared about out of subversion. It was useful at the time I set it up 6 or so years ago, but other/better options exist now.</li>
<li>MediaWiki, most of the stuff in there was either related to a project in Subversion. So I&#8217;ll switch to using the github wiki associated with a project. No need to worry about security or keeping software up to date.</li>
</ul>


<p>So all in all a success switching to Ubuntu.</p>

<p>Now onto my wish list:</p>

<ul>
<li>Ruby/Rails using passenger and Postgres, for messing about with personal projects.</li>
<li>Virtual hosts in Apache or even switch to nginx</li>
<li>Monitoring system stats like Memory/CPU etc</li>
<li>DNS within home network so I can setup aliases like dns.home</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[IntelliJ IDEA Ubuntu Launcher]]></title>
    <link href="http://lambdafoo.com/blog/2010/12/17/intellij-idea-ubuntu-launcher/"/>
    <updated>2010-12-17T00:00:00+11:00</updated>
    <id>http://lambdafoo.com/blog/2010/12/17/intellij-idea-ubuntu-launcher</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been using IntelliJ on Ubuntu 10.10 lately for work and rather than
starting things from the terminal I wanted a pretty launcher in the top menu.</p>

<p>After a quick search I found this site:</p>

<p><a href="http://www.dotkam.com/2010/06/16/intellij-idea-ubuntu-launcher/">IntelliJ Ubuntu Launcher</a></p>

<p>Following the instructions yielded a pretty launcher to sit in my top menu bar.</p>

<p>The only improvement I could add is to have an <strong>/opt/intellij-current</strong> directory and use</p>

<pre><code>sudo ln -s /opt/idea-IU-99.18 /opt/idea-current
</code></pre>

<p>to redirect it around to point to the current version of IntelliJ you have.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Leaving OpenBSD for]]></title>
    <link href="http://lambdafoo.com/blog/2010/09/30/leaving-openbsd-for/"/>
    <updated>2010-09-30T00:00:00+10:00</updated>
    <id>http://lambdafoo.com/blog/2010/09/30/leaving-openbsd-for</id>
    <content type="html"><![CDATA[<p>I&#8217;m migrating my home server away from OpenBSD.</p>

<p>The things I was able to setup in OpenBSD have worked very well. Things like
DHCP, DNS and SQUID have worked excellently. I found some fantastic guides on
http://www.kernel-panic.it/openbsd.html that allowed me to
get everything up and working in no time at all. I wont bother posting any
details from my setup it&#8217;s better to just visit that site and decide which
pieces you want.</p>

<p>Why move away? These are surely very personal reasons to make the switch and are
not a general condemnation of OpenBSD which is still a fantastic piece of
software.</p>

<ol>
<li><p>I wasn&#8217;t able to get DHCP &amp; DNS to dynamically update DNS when a new host
was added to the network. Instead I had a whole heap of static mappings for
computers. Not an ideal situation!</p></li>
<li><p>The upgrade path for OpenBSD confuses me. When a new version comes out how do
I upgrade without nuking all my local configuration? I really don&#8217;t want to
go back through the setup every 6 months when the BSD guys bring out a new
version.</p></li>
<li><p>I wasn&#8217;t able to get PHP + MySQL + Wordpress to play nicely together. Not
being a PHP person I didn&#8217;t really grok how to setup the whole thing so I
was forced to follow guides written by others. OpenBSD doesn&#8217;t really seem
to be a Wordpress/PHP platform of choice for many so I struggled to find
accurate docs on what to do.</p></li>
<li><p>I wanted to add new services to the server like Ruby/Rails, Java/EE,
Python/Django and Erlang/OTP. Doing all this and keeping it current on OpenBSD
is more work that I was willing to expend.</p></li>
</ol>


<p>So the solution I&#8217;m turning to is Linux and specifically Ubuntu in all it&#8217;s glory.</p>

<p>What a spiffy system Ubuntu is? I remember struggling to install Debian way back
when but Ubuntu is a pleasure and perhaps a little too easy. Kids these days
don&#8217;t need to struggle for hours setting up XFree86 or a dodgy network card.</p>

<p>So over the next few weeks I&#8217;m migrating the essential services, DHCP, DNS and
SQUID to Ubuntu. After that I&#8217;ll get a bit funky and start adding this blog on
there and other bits and pieces.</p>

<p>Hooray for Ubuntu!!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Thoughts on ObjectiveC and Cocoa]]></title>
    <link href="http://lambdafoo.com/blog/2010/08/24/thoughts-on-objectivec-and-cocoa/"/>
    <updated>2010-08-24T00:00:00+10:00</updated>
    <id>http://lambdafoo.com/blog/2010/08/24/thoughts-on-objectivec-and-cocoa</id>
    <content type="html"><![CDATA[<p>I wanted to collect my initial impressions of ObjectiveC and Cocoa. I&#8217;ve started
reading the Hillegas book again after and interrupted start last year with the
goal of doing a lot more osx coding in the future.</p>

<p>The things I&#8217;m enjoying most about the language are:</p>

<ul>
<li>the message passing nature of the method calls. It just seems like the right
 thing to do especially after experiencing Erlang and Ruby which both feature
 message passing.</li>
<li>the Cocoa APIs are beautifully self documenting and often read like pseudo
code.</li>
<li>the fantastic use of Design Patterns within Cocoa, you can really see the
benefits I using things like Delegates after spending some time doing ObjC.</li>
</ul>


<p>The downsides so far are limited to manual memory management within
ObjC. Granted there is a garbage collector on OSX but not on iPhones etc, so the
common wisdom seems to be you need to know how to use both. I don&#8217;t see this
will be an insurmountable problem as I managed to learn it for C++ which was a
much larger language.</p>

<p>The Hillegas book I&#8217;m using is brilliant but what would you expect from a guy
that has run training course on the subject for so long. The book does feel like
running through a training course but one run by a guy genuinely exciting about
the subject. My only wish is that there was an equivalent for the iPhone /
iPad.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[.emacs publishing]]></title>
    <link href="http://lambdafoo.com/blog/2010/06/25/emacs-publishing/"/>
    <updated>2010-06-25T00:00:00+10:00</updated>
    <id>http://lambdafoo.com/blog/2010/06/25/emacs-publishing</id>
    <content type="html"><![CDATA[<p>I signed up for a BitBucket account earlier this month but I&#8217;ve only recently
got around to using it. My first public project is my .emacs file. Check it out
at <a href="http://bitbucket.org/lambda_foo/.emacs">lambda_foo/.emacs</a>.</p>

<p>Includes partially working setup for:</p>

<ul>
<li>CommonLisp and SLIME</li>
<li>Erlang/OTP</li>
<li>Ruby</li>
<li>Haskell</li>
<li>Groovy</li>
</ul>


<p>The whole config is split into individual lisp files that are specific to a
language or cross cutting feature. The inspiration for doing this work came
from <a href="http://www.emacsblog.org/2007/10/07/declaring-emacs-bankruptcy/">M-x all-things-emacs</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Declaring .emacs Bankruptcy]]></title>
    <link href="http://lambdafoo.com/blog/2010/06/25/declaring-.emacs-bankruptcy/"/>
    <updated>2010-06-25T00:00:00+10:00</updated>
    <id>http://lambdafoo.com/blog/2010/06/25/declaring-.emacs-bankruptcy</id>
    <content type="html"><![CDATA[<p>Well really this is a post bankruptcy posting!</p>

<p>What? Cleanup .emacs file impossible you say. It must gather sediment like
sandstone until you have a tremendous hard packed conglomeration of ideas, never
daring to change something unless it breaks and not knowing if it worked in the
first place.</p>

<p>The Motivation: Messy configuration file, no organisation, unused configuration/modes.</p>

<p>The Solution: Remembering a link I archived in delicious some time ago, I revisited their ideas.</p>

<p>What I got was a very short .emacs file that only has some Load Path additions
and a heap of require statements for each customisation broken down into modes
or languages.</p>

<p>I really like this because it&#8217;s quite simple to add a new mode or customise and
existing one. Plus moving between Mac OS, Linux and BSD is a breeze, and sharing
a config file for a particular mode is soooo much easier.</p>

<p>I highly recommend doing this sort of clean up to your own .emacs.
After all who doesn&#8217;t like an organised workspace!</p>

<p>Original motivation here: <a href="http://www.emacsblog.org/2007/10/07/declaring-emacs-bankruptcy/">http://www.emacsblog.org/2007/10/07/declaring-emacs-bankruptcy/</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[eBook Thoughts]]></title>
    <link href="http://lambdafoo.com/blog/2010/05/05/ebook-thoughts/"/>
    <updated>2010-05-05T00:00:00+10:00</updated>
    <id>http://lambdafoo.com/blog/2010/05/05/ebook-thoughts</id>
    <content type="html"><![CDATA[<p>I&#8217;ve become a convert to the whole ebook thing recently, but only in a limited
capacity.</p>

<p>I still like having a paper book for most things I read like history and
fiction. The real value comes from replacing all those technical books that you
buy, like Java EE in 5 days.</p>

<p>There is a small subset of all the technical books I have that I really want a
paper copy of. Stuff like my Operating System books that you cannot get anymore
or are nice to have sitting on the bookshelf. But in general technical books
date so quickly that if you&#8217;re looking at something more that a year and a half
old it&#8217;s pretty much useless. The same goes for buying new book, I&#8217;ve started
asking myself the question <em>Am I going to read this in the next 6 months?</em> if
the answer is no then I don&#8217;t get the book. The only value in buying a technical
book lies in actually learning the content of it, not in decorating your
bookshelf.</p>

<p>Looking at my current bookshelf, there is probably half or more books that are
severly outdated and aren&#8217;t any use in their current form. I&#8217;m currently in the
process of thinning out their numbers.</p>

<p>What I&#8217;m planning on doing in the future is grabbing an eBook reader (and using
my MBP) and keeping all my technical books there. Basically treating technical
books more like magazines or newspapers, not that I really buy either of those
anymore.</p>
]]></content>
  </entry>
  
</feed>
