<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://brokenco.de//feed/by_tag/programming.xml" rel="self" type="application/atom+xml" /><link href="https://brokenco.de//" rel="alternate" type="text/html" /><updated>2026-07-12T13:39:01+00:00</updated><id>https://brokenco.de//feed/by_tag/programming.xml</id><title type="html">rtyler</title><subtitle>a moderately technical blog</subtitle><author><name>R. Tyler Croy</name></author><entry><title type="html">Finally understanding Rust</title><link href="https://brokenco.de//2019/12/01/rust-breakthrough.html" rel="alternate" type="text/html" title="Finally understanding Rust" /><published>2019-12-01T00:00:00+00:00</published><updated>2019-12-01T00:00:00+00:00</updated><id>https://brokenco.de//2019/12/01/rust-breakthrough</id><content type="html" xml:base="https://brokenco.de//2019/12/01/rust-breakthrough.html"><![CDATA[<p>This year I have been struggling to learn <a href="https://rust-lang.org">Rust</a>, but I am now pleased
to share that I’m <em>finally</em> understanding the language. <a href="/2019/04/02/struggling-with-rust.html">Earlier</a> I lamented the challenges of
adopting Rust. Between semantically important apostrophes and
angle-brackets a plenty, I was struggling to read and write basic Rust.
I can easily read Ada, C, Python, JavaScript, Java, and Ruby. Something about
the syntax of Rust remained difficult to process. The code looked jarring and
dissonant, I could read snippets but translating entire functions or modules
into a workable mental model was not feasible. Over the past month however, I
believe I have made some progress up the learning curve. I can now write
some Rust!</p>

<p>Getting over the hump required more effort than I had hoped, but after some small practice exercises I had the confidence and skills to move on to less trivial Rust.
I am not one for solving <a href="https://projecteuler.net/">Project
Euler</a> problems but instead I focused on porting
little utilities which I regularly use in my local environment. The
main educational benefit of these utilities is that none of them required network I/O, which is
what always really interests me about writing software. Instead these utilities
have very fixed inputs and outputs.  A small well-understood problem domain
made it <strong>much</strong> easier for me to clear my head and focus on the reading and
writing of Rust.</p>

<p>I also purchased a paper copy of the <a href="https://doc.rust-lang.org/book/">Rust Programming Language
book</a>. I’m not one for reading programming books
cover-to-cover, but having a paper copy still turned out to be useful. Taking the
paper copy to another location, <em>away from the computer</em>, allowed me to focus
on a few key chapters which addressed key areas of my confusion. The book is
written quite well, plenty of strong narrative explaining concepts behind Rust
rather than solely focusing on code snippets and the explanation that surrounds
them. Among other things, the narrative helped me wrap my brain around the zen
and art of ownership, a key concept to Rust if you’re to build anything
consequential with it.</p>

<p>Finally, I have started to read <em>more</em> Rust, which also helped me up the
learning curve. The convention of an <code class="language-plaintext highlighter-rouge">examples/</code> directory in
<a href="https://crates.io">Crates</a> has proven itself invaluable. Example snippets for
crates which do interesting things, or interface with systems that I am also
interested in working with, gave me a better feel of the syntax, structure, and
overall aesthetic of Rust.</p>

<p>I still struggle with the myriad of built-in modules in the standard library,
but I know that to be unavoidable from my time in the Java ecosystem. As one
writes more and more, slowly but surely the standard library seeps into the
muscle memory as if through osmosis. It just takes time.</p>

<p>Perhaps the learning curve would not have felt so steep if I had been able to
dedicate a week or two to the exercise of learning a new and structurally
different systems programming language. Once upon a time I could have
dedicated that much effort to such a hobby but those days are long gone now.
Instead I find myself picking up an hour here, thirty minutes there, and trying
to load mental context fast enough to make some progress with learning a new
skill. That approach might work for simple things, but Rust definitely was not
that to me.</p>

<p>If you are an experienced developer learning any new language of sufficient
newness, I would encourage you to think about how you learned to program in the
first place. Simple, small, almost embarrassingly basic exercises. The complex
systems you are capable of modeling will have to wait, you may have to go back
to the beginning. Back to the third, fourth, and fifth exercises after your
“Hello World.” It is painful, but this time around it will go much faster
than the first.</p>]]></content><author><name>R. Tyler Croy</name></author><category term="programming" /><category term="rust" /><summary type="html"><![CDATA[This year I have been struggling to learn Rust, but I am now pleased to share that I’m finally understanding the language. Earlier I lamented the challenges of adopting Rust. Between semantically important apostrophes and angle-brackets a plenty, I was struggling to read and write basic Rust. I can easily read Ada, C, Python, JavaScript, Java, and Ruby. Something about the syntax of Rust remained difficult to process. The code looked jarring and dissonant, I could read snippets but translating entire functions or modules into a workable mental model was not feasible. Over the past month however, I believe I have made some progress up the learning curve. I can now write some Rust!]]></summary></entry><entry><title type="html">Async sockets in Ada</title><link href="https://brokenco.de//2013/04/07/async-with-ada.html" rel="alternate" type="text/html" title="Async sockets in Ada" /><published>2013-04-07T00:00:00+00:00</published><updated>2013-04-07T00:00:00+00:00</updated><id>https://brokenco.de//2013/04/07/async-with-ada</id><content type="html" xml:base="https://brokenco.de//2013/04/07/async-with-ada.html"><![CDATA[<p>Recently I’ve been experimenting with the concept of a high-performance (high
parallelism, high concurrency, low CPU/memory footprint) TCP server in Ada. Developing on
top of Linux, you cannot help avoid the
<a href="https://en.wikipedia.org/wiki/epoll">epoll(7)</a> I/O event notification
system.</p>

<p>Unlike my previous post <a href="/2013/03/09/dynamic-tasks-in-ada.html">on dynamic task creation in
Ada</a>, this post won’t have much in the
way of sample code and walk-through. Mostly because I didn’t want to spend the
entire post explaining <code class="language-plaintext highlighter-rouge">epoll(7)</code> concepts.</p>

<p>If you’re currently unfamiliar with
epoll, I found <a href="https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/">this post from
banu.com</a>
interesting and useful. In general, I think that it is very useful to
understand how both <code class="language-plaintext highlighter-rouge">epoll(7)</code> and its BSD-friendly pal <code class="language-plaintext highlighter-rouge">kqueue(2)</code> work, and
how the two have influenced evented I/O systems that have become popular in the
past few years.</p>

<p>For my experiment, the primary challenge with using <code class="language-plaintext highlighter-rouge">epoll(7)</code> is wrapping the
C code with Ada, which on its face this isn’t terribly difficult. That said,
mapping C arrays and other stupid pointer tricks that C libraries are prone to
using, can make writing an Ada binding much more difficult. I don’t
intend to dive too deep into how one can create such a binding since I think
Felix Krause’s post on <a href="http://flyx.org/2012/06/13/adabindings1/">writing thin/thick C bindings in
Ada</a> is a pretty good introduction on
that subject. Personally I prefer “thicker” bindings for use in Ada, just as I
expect Ruby libraries to abstract away the more fickle aspects of the
underlying C API.</p>

<p>What I <em>did</em> want to share in this post was the actual <strong>working</strong> results of
my tinkering, which can be found <a href="https://github.com/rtyler/ada-playground/tree/master/epollecho">here, on GitHub</a>.</p>

<p>The basic flow of the program (found in <code class="language-plaintext highlighter-rouge">main.adb</code>) is similar to the example
found in the <code class="language-plaintext highlighter-rouge">epoll(7)</code> man page, in that it sets up the <code class="language-plaintext highlighter-rouge">epollfd</code>, binds the
listening to it and then waits for <code class="language-plaintext highlighter-rouge">Epoll.Wait</code> to return with an array of
socket descriptors which have activity on them.</p>

<p>My next step is to combine this <a href="https://github.com/rtyler/ada-playground/blob/master/epollecho/src/epoll.ads">basic epoll
binding</a>
with my <a href="/2013/03/09/dynamic-tasks-in-ada.html">previous task related
code</a> and create a TCP server which uses
a task pool to perform “work” on the incoming sockets given to it by an
epoll-listener task.</p>]]></content><author><name>R. Tyler Croy</name></author><category term="programming" /><category term="ada" /><category term="epoll" /><category term="async" /><summary type="html"><![CDATA[Recently I’ve been experimenting with the concept of a high-performance (high parallelism, high concurrency, low CPU/memory footprint) TCP server in Ada. Developing on top of Linux, you cannot help avoid the epoll(7) I/O event notification system.]]></summary></entry><entry><title type="html">Safe, Dynamic Task Creation in Ada</title><link href="https://brokenco.de//2013/03/09/dynamic-tasks-in-ada.html" rel="alternate" type="text/html" title="Safe, Dynamic Task Creation in Ada" /><published>2013-03-09T00:00:00+00:00</published><updated>2013-03-09T00:00:00+00:00</updated><id>https://brokenco.de//2013/03/09/dynamic-tasks-in-ada</id><content type="html" xml:base="https://brokenco.de//2013/03/09/dynamic-tasks-in-ada.html"><![CDATA[<p>A few years ago,
[Ada](https://secure.wikimedia.org/wikipedia/en/wiki/Ada_(programming_language)
became my hobby/tinker programming language of choice, for a <a href="/2010/12/06/ada-surely-you-jest-mr-pythonman.html">number of
reasons</a>, concurrency being
one of them. In this post I’d like to walk you through an example of dynamic
task creation in Ada, which uses <code class="language-plaintext highlighter-rouge">Ada.Task_Termination</code> handlers, a new feature
in Ada 2005.</p>

<p>(If you’re familiar with Ada, you can skip this next section)</p>

<hr />

<blockquote>
  <p><em>Note:</em> You can find all this code, and more in my
<a href="https://github.com/rtyler/ada-playground">ada-playground</a> repository on GitHub</p>
</blockquote>

<hr />

<p>Similar to C, Ada supports stack allocated variables as well as heap allocated
variabels, it also defaults to stack allocation. For example:</p>

<figure class="highlight"><pre><code class="language-ada" data-lang="ada">    <span class="kd">procedure</span> <span class="nf">Main</span> <span class="k">is</span>
        <span class="c1">-- A stack allocated `Integer` object</span>
        <span class="n">Enough_Memory</span> <span class="p">:</span> <span class="k">constant</span> <span class="nb">Integer</span> <span class="o">:=</span> <span class="mi">655360</span><span class="p">;</span>
    <span class="k">begin</span>
        <span class="k">null</span><span class="p">;</span>
    <span class="k">end</span> <span class="n">Main</span><span class="p">;</span></code></pre></figure>

<p>If you wanted to allocate that <code class="language-plaintext highlighter-rouge">Integer</code> onto the heap, then you would use the
<code class="language-plaintext highlighter-rouge">new</code> keyword:</p>

<figure class="highlight"><pre><code class="language-ada" data-lang="ada">    <span class="kd">procedure</span> <span class="nf">Main</span> <span class="k">is</span>
        <span class="c1">-- A heap allocated `Integer` pointer</span>
        <span class="n">Enough_Memory</span> <span class="p">:</span> <span class="k">access</span> <span class="nb">Integer</span> <span class="o">:=</span> <span class="k">new</span> <span class="nb">Integer</span><span class="p">'(</span><span class="mi">655360</span><span class="p">);</span>
    <span class="k">begin</span>
        <span class="k">null</span><span class="p">;</span>
    <span class="k">end</span> <span class="n">Main</span><span class="p">;</span></code></pre></figure>

<p>I won’t dive too much into the minutia of what is going on here, if you’re not
familiar with Ada already you can learn more about <a href="http://en.wikibooks.org/wiki/Ada_Programming/Types/access">access types on the Ada
Programming
Wikibook</a>. Basically
we’re heap allocating a new Integer and using an  <strong>access type</strong> (aka: typed
pointer) to keep track of it. Keen readers will notice we didn’t do anything
with that Integer access type, and we’re <em>technically</em> leaking the memory. To
solve this we use the generic unit <code class="language-plaintext highlighter-rouge">Ada.Unchecked_Deallocation</code>, which gives
you a facility for properly freeing memory (<a href="http://en.wikibooks.org/wiki/Ada_Programming/Types/access#Deleting_objects_from_a_storage_pool">more details
here</a>).</p>

<hr />

<h3 id="tasking-trickiness">Tasking Trickiness</h3>

<p>Concurrency is part of the language in Ada, and is handled through
<a href="http://en.wikibooks.org/wiki/Ada_Programming/Tasking">tasking</a>. A basic
example of might be:</p>

<figure class="highlight"><pre><code class="language-ada" data-lang="ada">    <span class="k">with</span> <span class="n">Ada</span><span class="p">.</span><span class="n">Text_IO</span><span class="p">;</span>
    <span class="kd">procedure</span> <span class="nf">Main</span> <span class="k">is</span>
        <span class="k">task</span> <span class="n">Counter</span><span class="p">;</span>
        <span class="k">task</span> <span class="k">body</span> <span class="n">Counter</span> <span class="k">is</span>
        <span class="k">begin</span>
            <span class="k">for</span> <span class="n">Count</span> <span class="k">in</span> <span class="mi">1</span> <span class="o">..</span> <span class="mi">10</span> <span class="k">loop</span>
                <span class="n">Ada</span><span class="p">.</span><span class="n">Text_IO</span><span class="p">.</span><span class="n">Put_Line</span> <span class="p">(</span><span class="n">Count</span><span class="p">'</span><span class="na">Img</span><span class="p">);</span>
            <span class="k">end</span> <span class="k">loop</span><span class="p">;</span>
        <span class="k">end</span> <span class="n">Counter</span><span class="p">;</span>
    <span class="k">begin</span>
        <span class="k">null</span><span class="p">;</span>
    <span class="k">end</span> <span class="n">Main</span><span class="p">;</span></code></pre></figure>

<p>The way tasks in Ada work means that the <code class="language-plaintext highlighter-rouge">Counter</code> task will be created,
started and then the execution of the <code class="language-plaintext highlighter-rouge">Main</code> program will block until the
<code class="language-plaintext highlighter-rouge">Counter</code> task completes (important detail).</p>

<p>The trickiness starts to arrive when you talk about dynamically allocating task
objects, and combine that with something like an infinite loop, such as one
might find in a server program, e.g.:</p>

<figure class="highlight"><pre><code class="language-ada" data-lang="ada">    <span class="kd">procedure</span> <span class="nf">Main</span> <span class="k">is</span>
    <span class="k">begin</span>
        <span class="c1">-- Socket set up omitted</span>
        <span class="k">loop</span>
            <span class="k">declare</span>
                <span class="n">Client_Socket</span> <span class="p">:</span> <span class="n">Socket_Type</span><span class="p">;</span>
                <span class="n">Request_Handler</span> <span class="p">:</span> <span class="n">Handler_Ptr</span> <span class="o">:=</span> <span class="k">new</span> <span class="n">Handler</span><span class="p">;</span>
            <span class="k">begin</span>
                <span class="c1">-- Block until we receive a new inbound connection</span>
                <span class="n">Accept_Socket</span> <span class="p">(</span><span class="n">Server_Socket</span><span class="p">,</span> <span class="n">Client_Socket</span><span class="p">,</span> <span class="n">Server_Addr</span><span class="p">);</span>
                <span class="c1">-- Dereference the Handler_Ptr and call `Process` on the Handler</span>
                <span class="c1">-- task</span>
                <span class="n">Request_Handler</span><span class="p">.</span><span class="k">all</span><span class="p">.</span><span class="n">Process</span> <span class="p">(</span><span class="n">Client_Socket</span><span class="p">);</span>
            <span class="k">end</span><span class="p">;</span>
        <span class="k">end</span> <span class="k">loop</span><span class="p">;</span>
    <span class="k">end</span> <span class="n">Main</span><span class="p">;</span></code></pre></figure>

<p>(The code above is an abbreviated version of <code class="language-plaintext highlighter-rouge">echomultitask_main.adb</code> which <a href="https://github.com/rtyler/ada-playground/blob/master/echomultitask_main.adb">can
be found
here</a>).</p>

<p>The issue with this code is that we’re allocating a new <code class="language-plaintext highlighter-rouge">Handler</code> task for
every in-bound connection, and we have no means of ever cleaning them up
properly. If we were to create an Array of <code class="language-plaintext highlighter-rouge">Handler_Ptr</code>, we still would have
to find some mechanism (which exists) to check the status of each <code class="language-plaintext highlighter-rouge">Handler</code> to
determine if we should clean it up. Problem being, we’d have to loop through
all the active tasks, checking for a “terminated” status, in order to
deallocate them. It’d be much better if a task could tell us when it’s
finished, rather than us polling every one.</p>

<p>Fortunately in Ada 2005, a mechanism was added to make it easier to add
“clean-up” to tasks: <strong><code class="language-plaintext highlighter-rouge">Ada.Task_Termination</code></strong>. The package allows you to set
up a termination handler for the a specific task, which the runtime will call
when that task terminates. <em>Unfortunately</em> however, the handler procedure that
can be invoked when the task terminates will <strong>not</strong> be passed a pointer to
the task itself, but rather the <code class="language-plaintext highlighter-rouge">Task_Id</code> (<code class="language-plaintext highlighter-rouge">Ada.Task_Identification.Task_Id</code>).</p>

<p><strong>So close</strong> to being able to properly deallocate these dynamic tasks, but we
need one more component, a protected object with a hash map inside of it:</p>

<figure class="highlight"><pre><code class="language-ada" data-lang="ada">    <span class="kd">package</span> <span class="nn">Server</span><span class="p">.</span><span class="nf">Handlers</span> <span class="k">is</span>
        <span class="k">protected</span> <span class="n">Coordinator</span> <span class="k">is</span>
            <span class="kd">procedure</span> <span class="nf">Track</span> <span class="p">(</span><span class="n">Ptr</span> <span class="p">:</span> <span class="k">in</span> <span class="n">Handler_Ptr</span><span class="p">);</span>
        <span class="k">private</span>
            <span class="n">Active_Tasks</span> <span class="p">:</span> <span class="n">Handler_Containers</span><span class="p">.</span><span class="n">Map</span><span class="p">;</span>
        <span class="k">end</span> <span class="n">Coordinator</span><span class="p">;</span>
    <span class="k">end</span> <span class="n">Server</span><span class="p">.</span><span class="n">Handlers</span><span class="p">;</span></code></pre></figure>

<p>Then back in <code class="language-plaintext highlighter-rouge">main.adb</code>:</p>

<figure class="highlight"><pre><code class="language-ada" data-lang="ada">    <span class="n">Accept_Socket</span> <span class="p">(</span><span class="n">Server_Socket</span><span class="p">,</span> <span class="n">Client_Socket</span><span class="p">,</span> <span class="n">Server_Addr</span><span class="p">);</span>
    <span class="n">Request_Handler</span><span class="p">.</span><span class="k">all</span><span class="p">.</span><span class="n">Process</span> <span class="p">(</span><span class="n">Client_Socket</span><span class="p">);</span>
    <span class="c1">-- Make sure the we keep track of the Request_Handler in order to properly</span>
    <span class="c1">-- deallocate it later</span>
    <span class="n">Server</span><span class="p">.</span><span class="n">Handlers</span><span class="p">.</span><span class="n">Coordinator</span><span class="p">.</span><span class="n">Track</span> <span class="p">(</span><span class="n">Request_Handler</span><span class="p">);</span></code></pre></figure>

<p>(The code above is an abbreviated version of <code class="language-plaintext highlighter-rouge">echomultitask-worker.ads</code> which
<a href="https://github.com/rtyler/ada-playground/blob/master/echomultitask-worker.ads">can be found
here</a>)</p>

<p>The singleton protected object <code class="language-plaintext highlighter-rouge">Coordinator</code> not only will give us protected
(aka thread safe) access to the <code class="language-plaintext highlighter-rouge">Active_Tasks</code> map, but also gives us a
protected object to hang our <code class="language-plaintext highlighter-rouge">Ada.Task_Termination.Termination_Handler</code>
protected procedure off of:</p>

<figure class="highlight"><pre><code class="language-ada" data-lang="ada">    <span class="k">protected</span> <span class="k">body</span> <span class="n">Server</span><span class="p">.</span><span class="n">Handlers</span> <span class="k">is</span>
        <span class="k">protected</span> <span class="k">body</span> <span class="n">Coordinator</span> <span class="k">is</span>
            <span class="kd">procedure</span> <span class="nf">Last_Wish</span> <span class="p">(</span><span class="n">C</span> <span class="p">:</span> <span class="n">Ada</span><span class="p">.</span><span class="n">Task_Termination</span><span class="p">.</span><span class="n">Cause_Of_Termination</span><span class="p">;</span>
                                <span class="n">T</span> <span class="p">:</span> <span class="n">Ada</span><span class="p">.</span><span class="n">Task_Identification</span><span class="p">.</span><span class="n">Task_Id</span><span class="p">;</span>
                                <span class="n">X</span> <span class="p">:</span> <span class="n">Ada</span><span class="p">.</span><span class="n">Exceptions</span><span class="p">.</span><span class="n">Exception_Occurrence</span><span class="p">)</span> <span class="k">is</span>
            <span class="k">begin</span>
                <span class="c1">-- Deallocate our task identified by `T`</span>
                <span class="c1">-- and make sure we remove it from `Active_Tasks`</span>
            <span class="k">end</span> <span class="n">Last_Wish</span><span class="p">;</span>
            <span class="kd">procedure</span> <span class="nf">Track</span> <span class="p">(</span><span class="n">Ptr</span> <span class="p">:</span> <span class="k">in</span> <span class="n">Handler_Ptr</span><span class="p">)</span> <span class="k">is</span>
                <span class="c1">-- Dereference our `Handler` task, and fish out its Task_Id</span>
                <span class="n">Handler_Id</span> <span class="p">:</span> <span class="n">Ada</span><span class="p">.</span><span class="n">Task_Idenfitication</span><span class="p">.</span><span class="n">Task_Id</span> <span class="o">:=</span> <span class="n">Ptr</span><span class="p">.</span><span class="k">all</span><span class="p">'</span><span class="na">Identity</span>
            <span class="k">begin</span>
                <span class="c1">-- Add `Handler_Id` to our `Active_Tasks` map</span>
                <span class="n">Active_Tasks</span><span class="p">.</span><span class="n">Insert</span> <span class="p">(</span><span class="n">Handler_Id</span><span class="p">,</span> <span class="n">Ptr</span><span class="p">);</span>
                <span class="c1">-- Set up the Last_Wish procedure to be executed after our task has</span>
                <span class="c1">-- terminated</span>
                <span class="n">Ada</span><span class="p">.</span><span class="n">Task_Termination</span><span class="p">.</span><span class="n">Set_Specific_Handler</span> <span class="p">(</span><span class="n">Handler_Id</span><span class="p">,</span> <span class="n">Last_Wish</span><span class="p">'</span><span class="na">Access</span><span class="p">);</span>
            <span class="k">end</span> <span class="n">Track</span><span class="p">;</span>
        <span class="k">end</span> <span class="n">Coordinator</span><span class="p">;</span>
    <span class="k">end</span> <span class="n">Server</span><span class="p">.</span><span class="n">Handlers</span><span class="p">;</span></code></pre></figure>

<p>(The code above is an abbreviated version of <code class="language-plaintext highlighter-rouge">echomultitask-worker.adb</code> which
<a href="https://github.com/rtyler/ada-playground/blob/master/echomultitask-worker.adb">can be found here</a>)</p>

<p>This approach will allow us to safely create new dynamic tasks to handle the
incoming requests, but will also make sure that the tasks are cleanly
deallocated when they terminate.</p>

<p>If you’re interested in concurrency in Ada, I
highly recommend purchasing <a href="http://www.amazon.com/gp/product/0521866979?ie=UTF8&amp;tag=unethicalblog-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0521866979">Concurrent and Real-Time Programming in
Ada</a>
by Alan Burns and Andy Wellings, it’s been tremendously helpful for my own
concurrency exploration in Ada.</p>]]></content><author><name>R. Tyler Croy</name></author><category term="ada" /><category term="programming" /><summary type="html"><![CDATA[A few years ago, [Ada](https://secure.wikimedia.org/wikipedia/en/wiki/Ada_(programming_language) became my hobby/tinker programming language of choice, for a number of reasons, concurrency being one of them. In this post I’d like to walk you through an example of dynamic task creation in Ada, which uses Ada.Task_Termination handlers, a new feature in Ada 2005.]]></summary></entry><entry><title type="html">Pairing with the fourth wall</title><link href="https://brokenco.de//2012/08/28/pairing-with-the-fourth-wall.html" rel="alternate" type="text/html" title="Pairing with the fourth wall" /><published>2012-08-28T00:00:00+00:00</published><updated>2012-08-28T00:00:00+00:00</updated><id>https://brokenco.de//2012/08/28/pairing-with-the-fourth-wall</id><content type="html" xml:base="https://brokenco.de//2012/08/28/pairing-with-the-fourth-wall.html"><![CDATA[<p>Some time ago I found myself captivated by watching another developer work. Not
anybody that I work with or know in person, but the infamous
<a href="https://twitter.com/notch">Notch</a>. Throught some twist of fate I stumbled
across a live stream of <a href="http://www.twitch.tv/notch/">his</a> and spent a
non-trivial amount of time watching boxes and code fly by in Eclipse.</p>

<p>Inspired, I figured I would try out the same set up on my own. The first major
hurdle to overcome was actually <em>streaming</em> my desktop to
<a href="http://justin.tv/agentdero">Justin.tv</a>. After a full evening of searching, and tinkering
with <code class="language-plaintext highlighter-rouge">ffmpeg</code>, I managed to get <a href="https://gist.github.com/3495063#file_screenstream.sh">this
script</a> working well
enough to send audio and video across the internets.</p>

<p>With the “infrastructure” figured out, I started hosting a couple of sessions
while I worked on projects that I’m passionate about. I found the live coding
concept immediately useful when I managed to get live help from an engineer at
<a href="http://puppetlabs.com">Puppet Labs</a> while I dug through the <code class="language-plaintext highlighter-rouge">Puppet::AST</code>
parsing code.</p>

<p>Taking the experiment further, I even tried helping some folks on IRC with
“live support sessions” which were so fruitful that I posted a couple videos
(<a href="https://www.youtube.com/watch?v=ZaF6tMGI0Ps&amp;feature=plcp">1</a>,
<a href="https://www.youtube.com/watch?v=S¸OHZ74KI&amp;feature=plcp">2</a>) from them. In the
office, I can say “hey, come over here and look at this” when others need help,
and the live coding stream allowed me to extend that concept to practically
anybody I wished to help.</p>

<p>I haven’t helped anybody in a few months now, I use my typically viewer-less
sessions to help me focus on a single project. Whenever I turn the stream on,
I’m pair-programming with a companion who may or may not be there (considering
the <code class="language-plaintext highlighter-rouge">#codingwithrtyler</code> channel on Freenode is generally empty, I’m guessing
there’s nobody watching), but I focus just as if I had another engineer sitting
next to me.</p>

<p>It’s almost like a weird hybrid of pair programming and <a href="https://en.wikipedia.org/wiki/Rubber_duck_debugging">rubber duck
debugging</a> now that I
think about it.</p>

<p>The projects I work are not nearly as visually pleasing as Minecraft, and I
don’t have the geek fame that Notch has but I’m perfectly content to stream <a href="http://justin.tv/agentdero">my
desktop</a> to zero viewers as long as it proves
useful for evening and weekend hack-sessions.</p>]]></content><author><name>R. Tyler Croy</name></author><category term="programming" /><category term="voyeurism" /><category term="justintv" /><summary type="html"><![CDATA[Some time ago I found myself captivated by watching another developer work. Not anybody that I work with or know in person, but the infamous Notch. Throught some twist of fate I stumbled across a live stream of his and spent a non-trivial amount of time watching boxes and code fly by in Eclipse.]]></summary></entry><entry><title type="html">Live Coding with ffmpeg and justin.tv</title><link href="https://brokenco.de//2012/04/04/live-coding-with-ffmpeg.html" rel="alternate" type="text/html" title="Live Coding with ffmpeg and justin.tv" /><published>2012-04-04T00:00:00+00:00</published><updated>2012-04-04T00:00:00+00:00</updated><id>https://brokenco.de//2012/04/04/live-coding-with-ffmpeg</id><content type="html" xml:base="https://brokenco.de//2012/04/04/live-coding-with-ffmpeg.html"><![CDATA[<p>Recently I’ve been experimenting with operating a live coding stream of my
desktop. What this means in practice is that I focus on a single project or set
of tasks for an hour or two, while streaming everything I do to my <a href="http://justin.tv/agentdero">channel on
justin.tv</a>.</p>

<p>Here’s a boring demonstration:</p>

<center>
<object type="application/x-shockwave-flash" height="300" width="400" id="clip_embed_player_flash" data="http://www.justin.tv/widgets/archive_embed_player.swf" bgcolor="#000000"><param name="movie" value="http://www.justin.tv/widgets/archive_embed_player.swf" /><param name="allowScriptAccess" value="always" /><param name="allowNetworking" value="all" /><param name="allowFullScreen" value="true" /><param name="flashvars" value="auto_play=false&amp;start_volume=25&amp;title=Demonstration of live coding&amp;channel=agentdero&amp;archive_id=313873687" /></object><br /><a href="http://www.justin.tv/agentdero#r=-rid-&amp;s=em" class="trk" style="padding:2px 0px 4px; display:block; width: 320px; font-weight:normal; font-size:10px; text-decoration:underline; text-align:center;">Watch live video from Live coding with @agentdero on Justin.tv</a>
</center>

<p>I’ll save my thoughts on how the experiment is going for a later blog post, in
this post I just wanted to share the <strong>how</strong>.</p>

<p>First I use this <code class="language-plaintext highlighter-rouge">~/bin/screenstream</code> script:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/bin/sh -xe

INFO=$(xwininfo -frame)
API_KEY="YOUR_API_KEY_GOES_HERE"

WIN_GEO=$(echo $INFO | grep -oEe 'geometry [0-9]+x[0-9]+' | grep -oEe '[0-9]+x[0-9]+')
WIN_XY=$(echo $INFO | grep -oEe 'Corners:\s+\+[0-9]+\+[0-9]+' | grep -oEe '[0-9]+\+[0-9]+' | sed -e 's/\+/,/' )
FPS="15"

INRES='1680x1010'
OUTRES='1280x720'

ffmpeg -f x11grab -s "$INRES" -r "$FPS" -i :0.0+$WIN_XY \
    -f alsa -ac 2 -i default -vcodec libx264  -s "$OUTRES"  \
    -acodec libmp3lame -ab 128k -ar 44100 -threads 0 \
    -f flv "rtmp://live.justin.tv/app/$API_KEY"
</code></pre></div></div>

<p>There’s a couple important things to mention about this:</p>

<ul>
  <li>The <code class="language-plaintext highlighter-rouge">xwininfo</code> invocation just gives me a cross-hairs cursor so I can select which window area I want to record. This doesn’t technically restrict <code class="language-plaintext highlighter-rouge">ffmpeg(1)</code> to just that window, rather it just grabs the offset from the window and uses those.</li>
  <li>The segment: <code class="language-plaintext highlighter-rouge">-f alsa -ac 2 -i default</code> pertains to the audio input. According to <code class="language-plaintext highlighter-rouge">arecord -L</code>, the pulse audio sink I should use is called “default”, on some machines it might be called “pulse”, your mileage may vary.</li>
  <li>I use the <code class="language-plaintext highlighter-rouge">pavucontrol</code> (GUI) tool to direct my audio out to the pulseaudio input, this allows me to share what I’m listening to with whoever is watching the stream.</li>
  <li>You’ll notice the <code class="language-plaintext highlighter-rouge">$INRES</code> and <code class="language-plaintext highlighter-rouge">$OUTRES</code> parameters, I am techically live-resizing the video on the fly, which takes up a lot of CPU power, you may or may not want to do this depending on your machine speed, size of your screen and the amount of desktop space you want to stream.</li>
</ul>

<p>That’s about all there is too it, I wish I could either take credit for the
script or at least attribute it, but I can do neither because I found it on a
forum some where and then quickly lost the link. Whoops.</p>]]></content><author><name>R. Tyler Croy</name></author><category term="programming" /><category term="livecoding" /><category term="justintv" /><summary type="html"><![CDATA[Recently I’ve been experimenting with operating a live coding stream of my desktop. What this means in practice is that I focus on a single project or set of tasks for an hour or two, while streaming everything I do to my channel on justin.tv.]]></summary></entry><entry><title type="html">Puppet/XML: A Brand New Synergy</title><link href="https://brokenco.de//2012/02/08/puppet-xml-a-brand-new-synergy.html" rel="alternate" type="text/html" title="Puppet/XML: A Brand New Synergy" /><published>2012-02-08T00:00:00+00:00</published><updated>2012-02-08T00:00:00+00:00</updated><id>https://brokenco.de//2012/02/08/puppet-xml-a-brand-new-synergy</id><content type="html" xml:base="https://brokenco.de//2012/02/08/puppet-xml-a-brand-new-synergy.html"><![CDATA[<p>During on of the last talks of the last day of <a href="http://www.fosdem.org">FOSDEM</a>,
some person asked in one of the tracks (paraphrased):</p>

<blockquote>
  <p>“<em>Why do we need tools like Puppet or Chef when we have XML?</em>”</p>
</blockquote>

<p>This question was relayed to me second-hand, so I apologize if I’m butchering
it. The question itself is so mind-boggling that I can only assume one of three
things about the asker:</p>

<ul>
  <li>He/she is a rather talented troll</li>
  <li>He/she has some crucial misunderstandings about configuration management, in
which case I’m hoping somebody politely explained things.</li>
  <li>He/she understands CM but has a serious fetish for XML.</li>
</ul>

<hr />

<p>Regardless of their intention, I have them to thank for inspiring what might
be the innovation breakthrough of 2012:</p>

<h3 id="puppetxml">Puppet/XML</h3>

<p>I’ve long found Puppet’s DSL syntax to be too sparse, easy to type and
semantically boring, take for example this block:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>class users {
    group {
        "tyler" :
            ensure =&gt; present;
    }
    user {
        "tyler" :
            require =&gt; Group["tyler"],
            ensure  =&gt; present;
    }
}
</code></pre></div></div>

<p>How terrible! Let’s turn that into <strong>Puppet/XML!</strong></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;?xml version="1.0"?&gt;
&lt;puppet&gt;
    &lt;classes&gt;
        &lt;class name="users"&gt;
            &lt;resources&gt;
                &lt;group name="tyler"&gt;
                    &lt;ensure&gt;present&lt;/ensure&gt;
                &lt;/group&gt;
                &lt;user name="tyler"&gt;
                    &lt;requires&gt;
                        &lt;require&gt;Group["tyler"]&lt;/require&gt;
                    &lt;/requires&gt;
                    &lt;ensure&gt;present&lt;/ensure&gt;
                &lt;/user&gt;
            &lt;/resources&gt;
        &lt;/class&gt;
    &lt;/classes&gt;
&lt;/puppet&gt;
</code></pre></div></div>

<p>Not only is that easier to understand, it’s more enterprise ready!</p>

<p>Currently <strong>Puppet/XML</strong> is in pre-alpha and in <a href="https://github.com/rtyler/puppet/tree/puppetxml">this repository on
GitHub</a>. Thus far it’s only
been tested with <code class="language-plaintext highlighter-rouge">puppet apply</code> (i.e. standalone mode) under
<a href="http://www.vagrantup.com">Vagrant</a>, an example run is below:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[default] Running Puppet with /tmp/vagrant-puppet/manifests/base.ppx...
stdin: is not a tty
Thanks for using Puppet/XML - A brand new synergy

info: Retrieving plugin
info: Applying configuration version '1328719113'
notice: /Stage[main]/Users/User[tyler]/ensure: created
notice: /Stage[main]//Node[default]/Group[puppet]/ensure: created
info: Creating state file /var/lib/puppet/state/state.yaml
notice: Finished catalog run in 0.62 seconds
</code></pre></div></div>

<p>Stay tuned for new innovations and more middleware that your enterprise can
leverage to help meet your business objectives.</p>

<hr />

<p><strong><em>Disclaimer:</em></strong> Unfortunately the code currently relies on transcribing the
Puppet/XML to Puppet’s “native” DSL, this means more complex things like
conditionals and function calls are not yet supported. After spending about an
hour and a half trying to generate the appropriate <code class="language-plaintext highlighter-rouge">Puppet::AST</code> structures, I
gave up and went the route which guaranteed lulz sooner.</p>]]></content><author><name>R. Tyler Croy</name></author><category term="stupidhacks" /><category term="programming" /><category term="puppet" /><summary type="html"><![CDATA[During on of the last talks of the last day of FOSDEM, some person asked in one of the tracks (paraphrased):]]></summary></entry><entry><title type="html">Real talk (about Smalltalk)</title><link href="https://brokenco.de//2012/01/14/realtalk.html" rel="alternate" type="text/html" title="Real talk (about Smalltalk)" /><published>2012-01-14T00:00:00+00:00</published><updated>2012-01-14T00:00:00+00:00</updated><id>https://brokenco.de//2012/01/14/realtalk</id><content type="html" xml:base="https://brokenco.de//2012/01/14/realtalk.html"><![CDATA[<p>Somehow I found myself reading an interesting article on Smalltalk yesterday
which led to a couple of comments in IRC:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tyler:  man, I am getting that "I should really learn smalltalk"
        feeling again
tyler:  everytime I get close I find myself downloading a squeak
        VM and then going "LOLWTF IS THIS SHIT"
</code></pre></div></div>

<p>I said this before I left the office and somewhere in the back of my mind I
kept thinking “why can’t I crack Smalltalk?” This continued through most of the
evening until 9 pm (21:00) rolled around and I decided that I wouldn’t let that
commie <a href="https://en.wikipedia.org/wiki/Alan_Kay">Alan Kay</a> defeat me.</p>

<p>After finding <a href="https://www.youtube.com/playlist?list=PL61A023880D3529DB&amp;feature=plcp">this fantastic series of
screencasts</a>
I set about learning some Smalltalk. Not enough to build anything major, but
enough to really understand Smalltalk’s core concepts.</p>

<p>In exploring the world of <a href="http://squeak.org/">Squeak</a>,
<a href="http://www.pharo-project.org/home">Pharo</a> and <a href="http://amber-lang.net/">Amber</a>
I believe I have experienced the full spectrum of emotions that my circuits
provide, all the way from unfettered rage to mild bemusement. Despite all of
this, around 2 a.m. I found myself lying awake in bed wanting to marvelling at
the design of the language and wanting to learn <em>more</em>.</p>

<p>A couple of things still bug the hell out of me:</p>

<ul>
  <li>The VM concept while novel is a completely jarring experience for anybody who
has done <strong>any</strong> programming in any other environment <em>ever</em>.</li>
  <li>I hate mice. I also have no trackpad on my laptop which means if i’m not at
my desk using a mouse-heavy program becomes painful (quite literally). Both
Squeak and Pharo have this sick mouse fetish that makes me want to <code class="language-plaintext highlighter-rouge">（╯°□°）╯︵┻━┻</code></li>
  <li>GNU/Smalltalk feels closer to development environments that I’m familiar with,
but VisualGST is incredibly buggy and I think part of what makes Smalltalk
special is the integrated “live environment.”</li>
</ul>

<hr />

<p>The things that I do <strong>really</strong> like however:</p>

<ul>
  <li>The integrated “live environment” is something out of programmer fairy tales.
Inspect/debug/edit anything and everything? Yes please!</li>
  <li>Everything is an object which receives messages, the syntax for conditionals helps drive it home. A
boolean object can receive an <code class="language-plaintext highlighter-rouge">ifTrue</code> or an <code class="language-plaintext highlighter-rouge">ifFalse</code> message which takes a
block argument. This means there is no real for <code class="language-plaintext highlighter-rouge">if</code> statements, it’s all
implemented with the basic Smalltalk primitives:
      1 &lt; 3
          ifTrue:  [Transcript show: ‘Truthy!’]
          ifFalse: [Transcript show: ‘Untruthy!’]
How about a for loop? Surely the language must have a for loop! No way
José! Instead an Array object just takes a <code class="language-plaintext highlighter-rouge">do</code> message with a block, fancy!
      #(‘tom’ ‘dick’ ‘harry’) do:
          [ :each | Transcript show: (‘Hello ‘, each); cr]</li>
  <li>No magic, that I’ve seen thus far. One of my biggest criticisms of Ruby comes
out of the Rails tradition of magic methods by using <code class="language-plaintext highlighter-rouge">method_missing</code> to
magically generate methods on-demand, leaving a system that’s abominably
difficult to inspect and debug. Thus far I’ve not found any slight-of-hand in
Smalltalk, which is a good thing.</li>
</ul>

<hr />

<p>I can really see where Objective-C pulled from Smalltalk having now experienced
some Smalltalk myself. That said, it’s rather unfortunate that C and some
additional custom bits have creeped into Objective-C making it less Smalltalky
than it once was.</p>

<p>I am definitely going to continue to tinker with Smalltalk, likely with
<a href="http://pharo-project.org/home">Pharo</a> as my VM of choice. My only concern is
that I will grow to resent the other languages I use regularly which feel
dumber than a language invented almost 40 years ago.</p>

<hr />

<p><strong>Update:</strong> <a href="http://sebastianconcept.com/brandIt/10-reasons-why-im-using-smalltalk-for-airflowing">This is the original
post</a>
that pushed me over the edge on tinkering with Smalltalk.</p>]]></content><author><name>R. Tyler Croy</name></author><category term="smalltalk" /><category term="opinion" /><category term="programming" /><summary type="html"><![CDATA[Somehow I found myself reading an interesting article on Smalltalk yesterday which led to a couple of comments in IRC:]]></summary></entry><entry><title type="html">The only problem with cucumber</title><link href="https://brokenco.de//2011/11/16/cukes-make-me-pukes.html" rel="alternate" type="text/html" title="The only problem with cucumber" /><published>2011-11-16T00:00:00+00:00</published><updated>2011-11-16T00:00:00+00:00</updated><id>https://brokenco.de//2011/11/16/cukes-make-me-pukes</id><content type="html" xml:base="https://brokenco.de//2011/11/16/cukes-make-me-pukes.html"><![CDATA[<p>I have been exploring the wide world of <a href="https://en.wikipedia.org/wiki/Behavior_Driven_Development">Behavior Driven
Development</a> lately
with <a href="http://cukes.info">Cucumber</a>. For the longest time I’ve been fascinated
with Cucumber from a conceptual standpoint; a written-word testing framework,
do go on! I’m quite pleased to finally be able to put it to good use with some
recent <a href="https://github.com/rtyler/jenkins-selenium-tests">projects</a> that I’ve been working on.</p>

<p>The <strong>only</strong> downside I’ve found, thus far for Cucumber comes down to the
use of the term “cukes” to describe Cucumber-based tests.</p>

<p>The word “cuke” or “cukes” simply has an unpleasant, wretched feeling to it. It
sounds like something unpleasant to get on your shoes. I really do not like
this word.</p>

<p>As such, I will henceforth refer to Cucumber-based tests as “<em>gherkins</em>” instead.</p>

<p>I look forward to writing plenty of posts in the future about creating high
quality gherkins for browser testing and cross-system testing, stay tuned!</p>

<hr />

<p>(I sure have been complaining about names a lot lately haven’t I?)</p>]]></content><author><name>R. Tyler Croy</name></author><category term="cucumber" /><category term="ruby" /><category term="programming" /><category term="opinion" /><summary type="html"><![CDATA[I have been exploring the wide world of Behavior Driven Development lately with Cucumber. For the longest time I’ve been fascinated with Cucumber from a conceptual standpoint; a written-word testing framework, do go on! I’m quite pleased to finally be able to put it to good use with some recent projects that I’ve been working on.]]></summary></entry><entry><title type="html">Inside ActiveRecord Joins, a quick note</title><link href="https://brokenco.de//2011/11/15/inside-activerecord-joins.html" rel="alternate" type="text/html" title="Inside ActiveRecord Joins, a quick note" /><published>2011-11-15T00:00:00+00:00</published><updated>2011-11-15T00:00:00+00:00</updated><id>https://brokenco.de//2011/11/15/inside-activerecord-joins</id><content type="html" xml:base="https://brokenco.de//2011/11/15/inside-activerecord-joins.html"><![CDATA[<p>There was once a time when I prided myself on my ignorance of SQL Joins,
foolishly proclaiming “if I need to use a JOIN, I’ve already screwed up.”</p>

<p>I’ve slightly changed my opinions since then, mostly because I can no longer
afford to avoid JOINs. Sometimes harsh reality is the best cure for young
idealism.</p>

<p>Anywho, what was my point again about joins?</p>

<p>Ah yes, joins in <a href="http://rubygems.org/gems/activerecord">ActiveRecord</a>. While
ActiveRecord is a very solid ORM gem for Ruby, it is not without it’s quirks.
Most of which come down to “magic” behavior or defaults you’ve assumed
incorrectly. As much as I would like to pontificate on the odd <code class="language-plaintext highlighter-rouge">method_missing</code>
magic ActiveRecord developers seem to love, this post is more about the latter.</p>

<p>In general, JOINs involve two tables, JOINing together the tables typically for
a nested query of some form or fashion. For an example, let’s use this make believe query:</p>

<figure class="highlight"><pre><code class="language-sql" data-lang="sql">    <span class="k">SELECT</span> <span class="nv">`guests`</span><span class="p">.</span><span class="o">*</span> <span class="k">FROM</span> <span class="nv">`guests`</span> <span class="k">JOIN</span> <span class="nv">`plates`</span> <span class="err">\</span>
        <span class="k">ON</span> <span class="n">plates</span><span class="p">.</span><span class="n">guest_id</span> <span class="o">=</span> <span class="n">guests</span><span class="p">.</span><span class="n">id</span> <span class="k">WHERE</span> <span class="err">\</span>
        <span class="p">(</span><span class="n">guests</span><span class="p">.</span><span class="n">favorite</span> <span class="o">=</span> <span class="s1">'sushi'</span> <span class="k">OR</span> <span class="n">plates</span><span class="p">.</span><span class="n">content</span> <span class="o">=</span> <span class="s1">'sushi'</span><span class="p">);</span></code></pre></figure>

<p>There are five basic JOINs in SQL land, and in this context they mean:</p>

<ul>
  <li><strong>LEFT JOIN</strong>: Find all the rows in <code class="language-plaintext highlighter-rouge">guests</code>, even if they don’t have a corresponding <code class="language-plaintext highlighter-rouge">plates</code> row, then apply sub-query.</li>
  <li><strong>RIGHT JOIN</strong>: Find all rows in <code class="language-plaintext highlighter-rouge">plates</code>, even if they don’t have a corresponding <code class="language-plaintext highlighter-rouge">guests</code> row, then apply sub-query.</li>
  <li><strong>INNER JOIN</strong>: Find rows <em>only</em> if <code class="language-plaintext highlighter-rouge">guests</code> has a corresponding <code class="language-plaintext highlighter-rouge">plates</code> row.</li>
  <li><strong>STRAIGHT JOIN</strong>: Find your way to the DBA’s desk and receive your punishment.</li>
  <li><strong>NATURAL JOIN</strong>: I’ll be honest, I don’t fully understand what a natural join does.</li>
</ul>

<p>Back in ActiveRecord land, let’s imagine I want to create a
<a href="http://apidock.com/rails/ActiveRecord/NamedScope/ClassMethods/named_scope">named_scope</a>,
which in Rails 3 has been deprecated in favor of just
<a href="http://apidock.com/rails/ActiveRecord/NamedScope/ClassMethods/scope">scope</a>,
I’d write code something like this:</p>

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby">    <span class="k">class</span> <span class="nc">Guest</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
      <span class="n">has_one</span> <span class="ss">:plate</span>
      <span class="c1"># ...</span>
      <span class="n">named_scope</span> <span class="ss">:with_food</span><span class="p">,</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="o">|</span><span class="n">food</span><span class="o">|</span> <span class="p">{</span>
                    <span class="ss">:conditions</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="s2">"guests.favorite = ? OR plates.content = ?"</span><span class="p">,</span> <span class="n">food</span><span class="p">,</span> <span class="n">food</span><span class="p">],</span>
                    <span class="ss">:joins</span> <span class="o">=&gt;</span> <span class="ss">:plate</span>
                <span class="p">}}</span>
    <span class="k">end</span></code></pre></figure>

<p>Underneath the hood, ActiveRecord generates a query <em>almost</em> exactly like the
one above with one subtle difference. “<code class="language-plaintext highlighter-rouge">JOIN</code>” is instead an “<code class="language-plaintext highlighter-rouge">INNER JOIN</code>”
which means my query will <em>not</em> return a Guest object for any guests who do not
already have a plate object.</p>

<p>The “solution” is to use a <code class="language-plaintext highlighter-rouge">LEFT JOIN</code>, which is unfortunately rather gnarly.
There may be a better way to perform alternate JOINs in ActiveRecord, but I
don’t yet of one:</p>

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby">    <span class="k">class</span> <span class="nc">Guest</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
      <span class="n">has_one</span> <span class="ss">:plate</span>
      <span class="c1"># ...</span>
      <span class="n">named_scope</span> <span class="ss">:with_food</span><span class="p">,</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="o">|</span><span class="n">food</span><span class="o">|</span> <span class="p">{</span>
                    <span class="ss">:conditions</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="s2">"guests.favorite = ? OR plates.content = ?"</span><span class="p">,</span> <span class="n">food</span><span class="p">,</span> <span class="n">food</span><span class="p">],</span>
                    <span class="ss">:joins</span> <span class="o">=&gt;</span> <span class="s2">"LEFT JOIN `plates` ON plates.guest_id = guests.id"</span>
                <span class="p">}}</span>
    <span class="k">end</span></code></pre></figure>

<p>Basically if you want to use anything other than a simple <code class="language-plaintext highlighter-rouge">INNER JOIN</code>, you’ve
got to enter it in yourself. At a certain point ActiveRecord throws up its
hands and says “Look, buddy, I have no idea what you’re trying to do here.
Enter your own damn SQL.”</p>]]></content><author><name>R. Tyler Croy</name></author><category term="ruby" /><category term="rails" /><category term="activerecord" /><category term="programming" /><summary type="html"><![CDATA[There was once a time when I prided myself on my ignorance of SQL Joins, foolishly proclaiming “if I need to use a JOIN, I’ve already screwed up.”]]></summary></entry><entry><title type="html">IO#popen can suck it</title><link href="https://brokenco.de//2011/11/12/popen-can-suck-it.html" rel="alternate" type="text/html" title="IO#popen can suck it" /><published>2011-11-12T00:00:00+00:00</published><updated>2011-11-12T00:00:00+00:00</updated><id>https://brokenco.de//2011/11/12/popen-can-suck-it</id><content type="html" xml:base="https://brokenco.de//2011/11/12/popen-can-suck-it.html"><![CDATA[<p><a href="https://twitter.com/jorgenpt/">Jørgen</a> pointed out that there’s no real
compelling reason to use <code class="language-plaintext highlighter-rouge">IO#popen</code> over a combo of <code class="language-plaintext highlighter-rouge">Open3#popen3</code> and
<code class="language-plaintext highlighter-rouge">IO#select</code>. That said, <code class="language-plaintext highlighter-rouge">Open3#popen3</code> is practically as brain-dead in 1.8 as
<code class="language-plaintext highlighter-rouge">IO#popen</code> is. Regardless, I’m not going to let that get in the way of a good cathartic rant (the changes in 1.9 are pretty sweet though).</p>

<hr />

<p>For better or worse, <a href="http://www.mylookout.com/about/jobs">Lookout</a> has
standardized on Ruby 1.8 in which I’ve discovered one absolutely <em>infuriating</em>
“quirk” with how <code class="language-plaintext highlighter-rouge">IO#popen</code> handles pipe redirection and spawning processes. A
“quirk” that has managed to screw me in more than two projects thus far. While
the issue affects both Ruby 1.8 and Ruby 1.9, there is no work-around in Ruby
1.8, which is especially frustrating.</p>

<p>When you execute <code class="language-plaintext highlighter-rouge">IO#popen</code>, you receive an <code class="language-plaintext highlighter-rouge">IO</code> object which implements some
methods which allow you to read <code class="language-plaintext highlighter-rouge">stdout</code> from the child process. Pretty
reasonable, sort of I guess, except that the new child process inherits the
parent’s <code class="language-plaintext highlighter-rouge">stderr</code> pipe. From the process table point of view, you will see
exactly what you expect:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>3046 pts/7    Ss     0:00 ruby demo.rb
9521 pts/7    R+     0:00  \_ run_daemon -f some.conf --verbose
</code></pre></div></div>

<p>Naturally you might want to redirect <em>all</em> the pipes in order to segment
the output of the spawned child process from the parent process. If you want to
separate them, i.e. a <code class="language-plaintext highlighter-rouge">child_stdout</code> and a <code class="language-plaintext highlighter-rouge">child_stderr</code> pipe, then the
<a href="http://www.ruby-doc.org/stdlib-1.9.3/libdoc/open3/rdoc/Open3.html#method-c-popen3">Open3#popen3</a>
has you covered.</p>

<p>What if you want to <em>combine</em> the two pipes (!) for reading inside of your
parent process? If for example, you’re wrapping a process and running
particular code depending on the collective output of the subprocess.</p>

<p><code class="language-plaintext highlighter-rouge">IO#popen</code> can do this with the magical “2&gt;&amp;1” token in your
command, e.g.:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>def spawn_and_watch
  @child = IO.popen("run_daemon -f some.conf --verbose 2&gt;&amp;1")

  Thread.new do
    while @child.gets |line| do
      # do magic
    end
  end
end
</code></pre></div></div>

<p>So that’s pretty disgusting just from the code standpoint. What’s even <strong>more</strong>
disgusting about this is what happens underneath the hood when you add the
“2&gt;&amp;1” token into the command:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>3046 pts/7    Ss     0:00 ruby demo.rb
9521 pts/7    R+     0:00  \_ sh -c run_daemon -f some.conf --verbose 2&gt;&amp;1
9522 pts/7    R+     0:00      \_ run_daemon -f some.conf --verbose
</code></pre></div></div>

<p>Subtle isn’t it?</p>

<center><img src="http://agentdero.cachefly.net/unethicalblogger.com/images/ohshit.jpg" alt="oh shit" /></center>

<p>This has wide-reaching consequences for the caller of
<code class="language-plaintext highlighter-rouge">IO#popen</code>, the returned <code class="language-plaintext highlighter-rouge">IO</code> object inside of my make believe
<code class="language-plaintext highlighter-rouge">spawn_and_watch</code> method has the <code class="language-plaintext highlighter-rouge">pid</code> of the <code class="language-plaintext highlighter-rouge">sh</code> executable. On top of that,
to the best of my knowledge there is no way to actually get a handle on the
<code class="language-plaintext highlighter-rouge">run_daemon</code> process ID that is now a grand-child process of <code class="language-plaintext highlighter-rouge">ruby demo.rb</code>. If
I do something as foolish as call: <code class="language-plaintext highlighter-rouge">Process.kill("TERM", @child.pid)</code> then I
will orphan my <em>actual process</em> and not get anything close to my desired
behavior.</p>

<p>Basically, using “2&gt;&amp;1” with <code class="language-plaintext highlighter-rouge">IO#popen</code> is only good if you want to orphan
processes, and prevent yourself from ever being able to send any signals to the
process you want. This handling of commands passed to <code class="language-plaintext highlighter-rouge">IO#popen</code> with the
“2&gt;&amp;1” token is consistent(ly bad) in both Ruby 1.8 and Ruby 1.9.</p>

<p>Fortunately for those using Ruby 1.9, you can work-around this behavior by
changing the above method to look like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>def spawn_and_watch
  @child = IO.popen(["run_daemon", "-f", "some.conf", "--verbose",
                                :err =&gt; [:child, :out]])
  # ...
end
</code></pre></div></div>

<p>It is because of this behavior alone that I have switched some personal
projects to default to Ruby 1.9.2 and above, which is nuts.</p>]]></content><author><name>R. Tyler Croy</name></author><category term="ruby" /><category term="programming" /><category term="opinion" /><category term="wtf" /><summary type="html"><![CDATA[Jørgen pointed out that there’s no real compelling reason to use IO#popen over a combo of Open3#popen3 and IO#select. That said, Open3#popen3 is practically as brain-dead in 1.8 as IO#popen is. Regardless, I’m not going to let that get in the way of a good cathartic rant (the changes in 1.9 are pretty sweet though).]]></summary></entry></feed>