<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
    <title>Radyology</title>
    
    <link rel="alternate" type="text/html" href="http://www.benrady.com/" />
    <id>tag:typepad.com,2003:weblog-1517578</id>
    <updated>2013-01-24T08:00:00-06:00</updated>
    
    <generator uri="http://www.typepad.com/">TypePad</generator>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Radyology" /><feedburner:info uri="radyology" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:browserFriendly></feedburner:browserFriendly><entry>
        <title>Poor Man's Location-based services with arp-scan and cron</title>
        <link rel="alternate" type="text/html" href="http://www.benrady.com/2013/01/poor-mans-location-based-services-with-arp-scan-and-cron.html" />
        <link rel="replies" type="text/html" href="http://www.benrady.com/2013/01/poor-mans-location-based-services-with-arp-scan-and-cron.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a00e54fb013da8834017d40654137970c</id>
        <published>2013-01-24T08:00:00-06:00</published>
        <updated>2013-01-24T08:00:00-06:00</updated>
        <summary>Have you ever wanted to have your computer do something when you came home, or when you left? Here's a cheap and easy way to do it. The arp-scan utility (available in most decent package managers) can scan your local...</summary>
        <author>
            <name>Ben Rady</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.benrady.com/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>Have you ever wanted to have your computer do something when you came home, or when you left? Here's a cheap and easy way to do it.</p>
<p>The <a href="http://linux.die.net/man/1/arp-scan" target="_self">arp-scan utility</a> (available in most decent package managers) can scan your local network for active network clients. Just use the --localnet option. If get a response from your mobile phone (identified by mac address) on your local network, then you're (probably) home! Here's an example:</p>
<pre><code>#!/bin/bash

if arp-scan --retry=3 --localnet | grep 'a4:a4:a6:a7:aa:ad'; then 
  echo "Daddy's home!"
else
  echo "Daddy's gone."
fi
</code></pre>
<p>Something like this could be easily run from cron (as root). A more sophisticated version would probably need to track the current state, possibly by touching and deleting a file, as to only act when it changes.</p>
<p>Something else to note: My phone, it seems to ignore too many arp requests in a row. Of course YMMV. Once a minute seems to work though. So the --retry option is in there just in case one of the arp packets gets lost.</p></div>
</content>



    </entry>
    <entry>
        <title>Arduino Controlled RC Car</title>
        <link rel="alternate" type="text/html" href="http://www.benrady.com/2013/01/arduino-controlled-rc-car.html" />
        <link rel="replies" type="text/html" href="http://www.benrady.com/2013/01/arduino-controlled-rc-car.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a00e54fb013da8834017d4033a2ee970c</id>
        <published>2013-01-22T08:00:00-06:00</published>
        <updated>2013-01-22T08:40:02-06:00</updated>
        <summary>The problem with RC cars and little kids is that RC cars are actually rather hard to control. And really, rather than standing there controlling the car, most kids would rather be chasing it around (at least, most of my...</summary>
        <author>
            <name>Ben Rady</name>
        </author>
        
        
<content type="html" xml:lang="en-US" xml:base="http://www.benrady.com/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;The problem with RC cars and little kids is that RC cars are actually rather hard to control. And really, rather than standing there controlling the car, most kids would rather be chasing it around (at least, most of my kids would).&lt;/p&gt;

&lt;p&gt;So I decided to see if I could build an RC car that drove itself, using an &lt;a href="http://arduino.cc/en/Main/ArduinoBoardNano"&gt;Arduino nano&lt;/a&gt; rather than a remote control.&lt;/p&gt;

&lt;h3&gt;Hardware&lt;/h3&gt;
&lt;p&gt;Here's the parts list (aside from wires, solder, etc...)&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://arduino.cc/en/Main/ArduinoBoardNano"&gt;Arduino Nano&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;PING))) Ultrasonic Distance Sensor &lt;a href="http://www.parallax.com/tabid/768/productid/92/default.aspx"&gt;($30 from Paralax.com)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;4 pin multicolor LED (Can't find a link now but &lt;a href="https://www.sparkfun.com/products/105"&gt;this is close&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Maisto Tech R/C Radio Control Rock Crawler Jr.&lt;a href="http://www.amazon.com/gp/search/ref=as_li_qf_sp_sr_tl?ie=UTF8&amp;keywords=B003DKO2EY&amp;tag=wwwbenradycom-20&amp;index=aps&amp;linkCode=ur2&amp;camp=1789&amp;creative=9325"&gt;($40 from Amazon.com)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first step was figuring out where the RC chip leads were connected.&lt;/p&gt;

&lt;p&gt;&lt;img src='http://benrady.typepad.com/photos/arduinocar/2013-01-05-133413.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;The answer turned out to be:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;R17 -- Backward&lt;/li&gt;
  &lt;li&gt;R18 -- Forward&lt;/li&gt;
  &lt;li&gt;R23 -- Right&lt;/li&gt;
  &lt;li&gt;R24 -- Left&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src='http://benrady.typepad.com/photos/arduinocar/2013-01-05-153139.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;After that, I just needed to wire those leads into the arduino. I started out testing with an Arduino Uno, and once everything was working, I wired it up to the Nano I bought to actually use in the car.&lt;/p&gt;

&lt;p&gt;&lt;img src='http://benrady.typepad.com/photos/arduinocar/2013-01-06-140803.jpg' alt='' /&gt;&lt;/p&gt;
&lt;p&gt; After I confirmed that was working, I put the car back together, drilled a hole in the top for the LED, and hot-glued the PING))) sensor to the front at about a 10 degree angle upwards.&lt;/p&gt;

&lt;h3&gt;Software&lt;/h3&gt;
&lt;p&gt;Arduino's libraries are so easy to work with, you almost forget you're writing C++. So I wrote a &lt;a href="https://github.com/benrady/Unicorn"&gt;simple program to control the car&lt;/a&gt;. Since there's only one ultrasonic sensor, I needed a simple approach to avoiding obstacles (Summary: turn left).&lt;/p&gt;

&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.youtube.com/watch?v=A5RkLIUZ5mQ&amp;feature=youtu.be"&gt;Here's the car driving around my toy-littered basement.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are still some improvements to be made here. Finding a car that ran on 9 volt power would have greatly simplified the design...although most of those cars are much more expensive than the one that I bought. And I need to add a switch to control the arduino.&lt;/p&gt;

&lt;p&gt;Of course, this begs the question, is it still an "RC" car if it's not controlled remotely?&lt;/p&gt;
&lt;/div&gt;
</content>



    </entry>
    <entry>
        <title>The Simplest Continuous Testing</title>
        <link rel="alternate" type="text/html" href="http://www.benrady.com/2012/11/the-simplest-continuous-testing.html" />
        <link rel="replies" type="text/html" href="http://www.benrady.com/2012/11/the-simplest-continuous-testing.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a00e54fb013da8834017d3df2e391970c</id>
        <published>2012-11-26T07:00:00-06:00</published>
        <updated>2012-11-26T07:00:00-06:00</updated>
        <summary>Here's a simple bash script I use to do things to files whenever they change. It takes a command as an argument and runs that command with the name of a changed file. Many times, it's all I need to...</summary>
        <author>
            <name>Ben Rady</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.benrady.com/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>Here's a simple bash script I use to do things to files whenever they change. It takes a command as an argument and runs that command with the name of a changed file. Many times, it's all I need to do continuous testing.</p>
<pre><code>
#!/bin/bash
# Requires that the inotify-tools package be installed.
wait_cmd="inotifywait -m -r --format %w%f -e modify ."
filter=$1
shift
cmd="$@"
$wait_cmd | grep --line-buffered $filter | while read file; do 
  clear
  $cmd $file
  date
done
</code></pre></div>
</content>



    </entry>
    <entry>
        <title>There's No Such Thing As Software Productivity</title>
        <link rel="alternate" type="text/html" href="http://www.benrady.com/2012/11/theres-no-such-thing-as-software-productivity.html" />
        <link rel="replies" type="text/html" href="http://www.benrady.com/2012/11/theres-no-such-thing-as-software-productivity.html" thr:count="18" thr:updated="2012-12-03T02:34:19-06:00" />
        <id>tag:typepad.com,2003:post-6a00e54fb013da8834017c322a989c970b</id>
        <published>2012-11-20T11:07:09-06:00</published>
        <updated>2012-11-20T11:04:53-06:00</updated>
        <summary>Bill Caputo, through repeated conversations we've had, has convinced me of something very surprising. It was something that changed the way I think about the world, and how I do my job. There is no such thing as software productivity....</summary>
        <author>
            <name>Ben Rady</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.benrady.com/">
<div xmlns="http://www.w3.org/1999/xhtml"><p><a href="https://twitter.com/logosity">Bill Caputo</a>, through repeated conversations we've had, has convinced me of something very surprising. It was something that changed the way I think about the world, and how I do my job.</p>

<p><strong>There is no such thing as software productivity.</strong></p>

<p><a href="http://www.martinfowler.com/bliki/CannotMeasureProductivity.html">As Martin Fowler observed</a> almost a decade ago, productivity in software cannot be usefully measured. The reason why is it just doesn't exist in The Realm of Relevant Things. Put another way, productivity has no applicability as a metric in software. "How much did we create today?" is not a relevant question to ask. Even if it could be measured, productivity in software does not approximate business value in any meaningful way.</p>

<p>This is because software development is not an activity that necessarily <em>produces</em> anything. Here's a thought experiment: Let's say that you have a couple of developers working on the same project, and by accident, both of them pick up the same task on the same day. The first one, Frank, hauls off and writes a 1000 line framework that solves the problem beautifully. The code is well written, well tested, and the deployment and operation of it is well documented. The second developer, Peter, heads off to to the park for the day, where he thinks about the problem while he feeds the pigeons. Around 4:45, Peter wanders back to the office, deletes 100 lines of code, deploys the change...and the problem is fixed.</p>

<p>Which of these two developers was more "productive" today? The answer is: It doesn't matter. What matters the that Peter solved the problem, while simultaneously reducing long term maintenance costs for the team. Frank also solved the problem, but he increased maintenance costs by <em>producing</em> code, and so (all other things being equal) his solution is inferior. To call Peter more "productive" is to torture the metaphor beyond any possible point of utility. </p>

<p>I would argue that what good software developers do is <strong>remove problems</strong>. The opposite, in fact, of production. The creation of technological artifacts such as code, documentation, data, etc...are all necessary evils to achieve the goal of removing problems. That's why, sometimes, the most effective solution to a problem is a 5 minute conversation.</p>

<p>The strongest evidence for this model is that when you look at software development this way, a large number of thorny, observable-but-unquantifiable problems suddenly become easy to understand. For example, why do developers (usually) seem to be less effective when you isolate them from stakeholders and/or users. Wouldn't keeping them from getting distracted make them more productive? The answer is yes, it does often make them more productive...but it also makes them less <em>effective</em>. Since what they're doing is solving problems for stakeholders, isolating them from those stakeholders makes it harder for them to identify and solve problems. Having access to the people whose problem is being solved is more effective than the alternative, even if it means not having hands-on-keyboards for 8 full hours a day.</p>

<p>Which leads us to another example: Why do maintenance costs usually (but not always) dwarf other costs in building software? Why can't we ever seem to get it "right" the first time? One explanation is that software is a <em>fixed solution</em> to a potentially changing problem. When the problem changes (or when our understanding of it changes), it creates a gap between the problem and the solution. It gets expensive to constantly fill these gaps over time as the problems shift, even though the software doesn't change unless we change it. This also explains why video games traditionally have low maintenance costs compared to other software projects. It could be that the problem being solved (getting people to buy and play the game) is mostly dependent on human psychology, and less likely to change.</p>

<p>What about the mythical 10x "productivity" difference between good and bad developers? Everyone claims to have seen it, and yet nobody seems to be able to measure it directly. This theory explains that too. Problem solving is a much easier thing to "lever" (in the financial sense) than productivity, which makes order-of-magnitude differences easier to achieve. Problem solving requires only information and insight. Either you have it or you don't. There are no raw materials, no throughput limits. It's not that the bad developers are typing slowly. It's not that they would do better if they just "tried harder". They just don't have the insight or the information to solve the problem as effectively. Perhaps the reason you can't measure the difference in productivity between the good and bad developer is because <strong>there's nothing to measure</strong>.</p>

<p>There may be other phenomena that this theory explains. You can probably figure them out if you try, anyway. Here's what I've been doing lately...try this and see if it works for you. Every time you catch yourself talking about being "productive", ask if you're approaching the problem in the right way. Remember that if we could solve the problem without making anything at all, anything that we actually <em>produce</em> is wasteful.</p></div>
</content>



    </entry>
    <entry>
        <title>How to Run Across a Lake</title>
        <link rel="alternate" type="text/html" href="http://www.benrady.com/2012/09/software-development-is-running-across-a-lake.html" />
        <link rel="replies" type="text/html" href="http://www.benrady.com/2012/09/software-development-is-running-across-a-lake.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a00e54fb013da8834017ee3ac9bbe970d</id>
        <published>2012-09-24T06:00:00-05:00</published>
        <updated>2012-09-24T06:00:00-05:00</updated>
        <summary>To run across a lake, you only have to do one thing: Run fast. The same is true in software development. Imagine you're running across a lake. As long as you're moving fast enough to make it from shore to...</summary>
        <author>
            <name>Ben Rady</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.benrady.com/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>To run across a lake, you only have to do one thing: Run fast. The same is true in software development.</p>

<p>Imagine you're running across a lake. As long as you're moving fast enough to make it from shore to shore without getting wet, you're fine. But as soon as you slow down, you're in trouble. Once your shoes start to get wet, it gets just a bit harder to run...and the slower you go, the faster you sink. All of the sudden, you're splashing in the lake, and your list of priorities goes from "go fast" to:</p>
<ol>
<li>Find out the nearest shoreline</li>
<li>Watch out for boats</li>
<li>Keep water out of your eyes</li>
<li>Try to keep your phone/wallet/keys dry</li>
<li>Take off shoes for to swim better</li>
<li>Learn to swim (OMG!)</li>
</ol>
<p>And so on...</p>
<p>Of course, all of these are just compensating for the fact that you're not running any more...you're swimming. And so it is with software. If you're moving fast...if you're staying out ahead of your customer's expectations, then everything is simple. Just keep moving fast and you'll be fine. <strong>People generally don't ask questions when they're getting what they want.</strong> When expectations aren't being met, however, all kinds of other concerns come into the picture.</p>
<p>In a corporate environment, falling into the lake usually manifests as status meetings, requests for estimates, change management constraints, and other distractions meant to "get things under control". When developing products, quite often you find yourself investing in better issue tracking and customer service, rather than adding value to your product. Ironically, in both cases, in order to mitigate the problems that you have, you wind up making the problems worse. Because you stopped being focused on delivering value, you created distractions, which means you have even less time to focus on delivering value.</p>
<p>It's a horrible place to be.</p></div>
</content>



    </entry>
    <entry>
        <title>An Apology of Sorts: Functional Languages Are (Still) Overrated</title>
        <link rel="alternate" type="text/html" href="http://www.benrady.com/2012/09/functional-languages-are-still-overrated.html" />
        <link rel="replies" type="text/html" href="http://www.benrady.com/2012/09/functional-languages-are-still-overrated.html" thr:count="5" thr:updated="2012-09-13T19:28:13-05:00" />
        <id>tag:typepad.com,2003:post-6a00e54fb013da88340177448cccf2970d</id>
        <published>2012-09-10T08:00:00-05:00</published>
        <updated>2012-09-10T08:00:00-05:00</updated>
        <summary>I vomited on the Internet. Then Hacker News picked it up.</summary>
        <author>
            <name>Ben Rady</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="Web/Tech" />
        
        
<content type="html" xml:lang="en-US" xml:base="http://www.benrady.com/">
&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;p&gt;Two years ago, I &lt;a href="http://www.benrady.com/2010/06/a-bit-of-heresy-functional-languages-are-overrated.html" target="_self"&gt;stood on my soapbox&lt;/a&gt; and yelled. I told the FP community that their languages were bad, and that they should feel bad. It was a post full of vitriol and frustration, but also a little bit of truth. I believed then (and still do) that functional languages are a poor solution if what you're looking for is a way to get B grade programmers to build scalable, concurrent systems. After trying to learn Erlang, Haskell, and then Scala, I couldn't see how using those languages was easier that just using separate processes, stitched together with message passing infrastructure, to build systems at scale. And with these thoughts running through my head, I vomited on the Internet. Then Hacker News picked it up.&lt;/p&gt;



&lt;p&gt;As is the custom on the web, almost none of the people who left comments actually tried to refute the central point of my post. Most of the responses I got were as angry and bitter as the post itself. I guess that's more evidence that, in this world, you get what you give. Thankfully though, some commenters were kind enough respond to my anger with offers of help. Some shared (rather excellent) resources for learning, others simply offered encouragement. But the most striking thing was a pattern that emerged from the comments that &lt;em&gt;did&lt;/em&gt; offer a counter to my central point. They all said the same thing: &lt;strong&gt;Try Clojure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After working with Clojure for the better part of this year, I can see why. Clojure is truly a joy. So much so, in fact, that I'm using it for some production systems at &lt;a href="http://www.drwtrading.com/"&gt;DRW&lt;/a&gt;, and on some of my side projects. Many of these systems are highly concurrent, doing work on dozens (and sometimes hundreds) of threads in parallel. The code is easy to reason about, easy to read, and easy to test. So &lt;strong&gt;I have to apologize&lt;/strong&gt; for taking what was a reasonable critique of various people promoting FP, and wrapping it in a very poorly written rant. If &lt;a href="http://www.benrady.com/2010/01/language-of-the-year-2010.html"&gt;I had decided&lt;/a&gt; to learn Clojure first, and had some success with it, maybe my post on FP would have been a little less rant-y.&lt;/p&gt;

&lt;p&gt;Even so, I'm glad to see that what got me so worked up in the first place has started to fade. People no longer seem to be equating &lt;a href="http://java.sys-con.com/node/419716"&gt;The Death of Moore's Law&lt;/a&gt; to "Everyone &lt;a href="http://www.drdobbs.com/tools/its-time-to-get-good-at-functional-progr/212201710"&gt;must learn functional programming, now&lt;/a&gt;. I understand why it's sometimes necessary to use hyperbole and bold claims to get people's attention. Once you have their attention, you can get your real point across. I just wish the focus back then was more on "[language] is awesome because of [language/platform feature]" and less about how we're all going to be out of a job&lt;/a&gt; unless we learn Caml (see what I did there?).&lt;/p&gt;

&lt;p&gt;In some ways, I feel like the FP community made the same mistake that people made with OOP 15 years ago: They turned a good idea into a fad. It moved the discussion away from the true merits of a language, and into the realm of doom, gloom, and hypothetical situations. People could &lt;a href="http://fupeg.blogspot.com/2011/06/concurrency-myth.html"&gt;clearly see&lt;/a&gt; that there is more than one way to skin a cat, especially on the web, where scale is often a requirement. But some FP proponents tried to cast the end of Moore's law as the end of all imperative programming...which is just silly. In any case, I think the fad is over, and most of what's left is truly good and useful. Introducing a functional language into your codebase still won't turn your team of B grade .NET developers into a bunch of &lt;a href="https://twitter.com/RoflscaleTips"&gt;roflscale&lt;/a&gt; ninja rockstars, but I don't think anyone's implying that anymore.&lt;/p&gt;&lt;p&gt;Let me end by passing on the advice that was given to me over two years ago: If you still haven't tried Clojure, I really suggest that you do. The &lt;a href="http://www.4clojure.com/"&gt;4Clojure&lt;/a&gt; puzzles are a great way to get started. They're actually quite simple (until they're not...that's the fun).&lt;/p&gt;

&lt;/div&gt;
</content>



    </entry>
    <entry>
        <title>The Case for Privacy (in Clojure)</title>
        <link rel="alternate" type="text/html" href="http://www.benrady.com/2012/09/the-case-for-privacy-in-clojure.html" />
        <link rel="replies" type="text/html" href="http://www.benrady.com/2012/09/the-case-for-privacy-in-clojure.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a00e54fb013da88340176177b57c7970c</id>
        <published>2012-09-04T07:00:00-05:00</published>
        <updated>2012-09-04T07:00:00-05:00</updated>
        <summary>A lot of people I've met don't use the private function definition in Clojure -- which is defn- if you've never seen it. They don't see the point, or they think that private functions in Clojure are dynfunctional (pun!). Based...</summary>
        <author>
            <name>Ben Rady</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.benrady.com/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>A lot of people I've met don't use the private function definition in Clojure -- which is <code>defn-</code> if you've never seen it. They don't see the point, or they think that private functions in Clojure are dynfunctional (pun!). Based on my use of it so far this year, this confuses me, because I think private functions in Clojure are awesome. The reason I think they're awesome is because I write tests for my code, so that I can refactor. Having a clear deliniation between code the that's tested directly and indirectly means I can refactor much more quickly.</p>

<p>When you're looking for ways to refactor code, you can use your fingers, or you can use your eyes. Refactoring with your fingers is nice. When you have a <a href="https://github.com/jakemcc/lein-autoexpect">continuous test runner</a>, running a suite of tests on each change, you can refactor pretty quickly. But refactoring with your eyes is much, much faster. <strong>Being able to see possible refactorings and think through them in your head is a much faster way to reason about how to clean up code.</strong></p>

<p>If most of your functions are private, you can refactor with your eyes before you refactor with your hands. Unless you've been doing something dumb like subverting access controls to invoke private functions, you know that all of your private functions can be changed, inlined, extracted, and generally recombobulated without fear of breaking a test or messing with another module. This frees up your mind to think about the code that's right in front of you, rather than worrying about the other code that might be calling it.</p>

<p>The public functions, on the other hand, are expensive to change. You will probably break some clients. You probably break tests. All of this will require a lot of work that, essentially, adds no value on it's own. That's not to say that you shouldn't refactor public functions, of course. It's just that the costs are potentially higher. And I find that too many public functions in a module create a slight reluctance to refactor. A pause in thinking, if you will, that I'd rather do without.</p>

<p>So I love private Clojure functions. They're just new a way to implement an old-fashioned idea: <a class="zem_slink" href="http://en.wikipedia.org/wiki/Encapsulation_%28object-oriented_programming%29" title="Encapsulation (object-oriented programming)" rel="wikipedia" target="_blank">Encapsulation</a>. Clearly dividing my clojure modules into public (more expensive to change) and private (less expensive to change) has worked out very well for me. If you haven't tried it, I suggest that you do.</p><p>Unless, of course, you're not writing tests...in which case I have nothing for you!</p>

</div>
</content>



    </entry>
    <entry>
        <title>Better Continuous Testing in JavaScript</title>
        <link rel="alternate" type="text/html" href="http://www.benrady.com/2012/08/better-continuous-testing-in-javascript.html" />
        <link rel="replies" type="text/html" href="http://www.benrady.com/2012/08/better-continuous-testing-in-javascript.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a00e54fb013da88340176177678a5970c</id>
        <published>2012-08-27T08:18:49-05:00</published>
        <updated>2012-08-27T08:18:49-05:00</updated>
        <summary>Things have come a long way since I wrote Continuous Testing in Ruby, Rails, and JavaScript. Lately, for JavaScript, I've been using John Bintz's jasmine-headless-webkit and his complementary guard plugin. This tool has some really awesome features, not the least...</summary>
        <author>
            <name>Ben Rady</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.benrady.com/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>Things have come a long way since I wrote <a href="http://www.amazon.com/Continuous-Testing-Ruby-Rails-JavaScript/dp/1934356700/">Continuous Testing in Ruby, Rails, and JavaScript</a>. Lately, for JavaScript, I've been using John Bintz's <a href="https://github.com/johnbintz/jasmine-headless-webkit/">jasmine-headless-webkit</a> and his <a href="https://github.com/johnbintz/guard-jasmine-headless-webkit">complementary guard plugin</a>.</p>

<p>This tool has some really awesome features, not the least of which is that the environment your tests run in is really webkit. That means that you don't have to mock out major parts of the browser environment like <code>window.location</code>, localStorage and sessionStorage, and XMLHttpRequest if you don't want to.</p>

<p>Another great feature is the ability to generate an html file that will run all your tests in a real browser, whenever guard runs tests. Combined with the <a href="https://chrome.google.com/webstore/detail/pilnojpmdoofaelbinaeodfpjheijkbh">Live Page</a> plugin for chrome, I get instant feedback about whether or not my Jasmine tests actually pass in the browser.</p>

<p>However, there is one downside compared the node.js technique I outlined in my book. jasmine-headless-webkit doesn't give you real stack traces in the guard output when tests fail. Usually this means you resort to looking at the test failure in the browser (using that generated html file). In practice, it's not a big deal, but it also means you need to make sure your tests pass in both environments, otherwise you might be stuck with a failing test that you can't diagnose. </p></div>
</content>



    </entry>
    <entry>
        <title>Released Jezebel 0.4</title>
        <link rel="alternate" type="text/html" href="http://www.benrady.com/2012/02/released-jezebel-04.html" />
        <link rel="replies" type="text/html" href="http://www.benrady.com/2012/02/released-jezebel-04.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a00e54fb013da8834016300d7e97f970d</id>
        <published>2012-02-06T08:32:46-06:00</published>
        <updated>2012-02-06T08:32:46-06:00</updated>
        <summary>I released version 0.4 of Jezebel last week. It now works with Node.js 0.6.2.</summary>
        <author>
            <name>Ben Rady</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.benrady.com/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>I released version 0.4 of Jezebel last week. It now works with Node.js 0.6.2.</p></div>
</content>



    </entry>
    <entry>
        <title>Continous Testing: with Ruby, Rails, and JavaScript -- Now in Print!</title>
        <link rel="alternate" type="text/html" href="http://www.benrady.com/2011/06/continous-testing-with-ruby-rails-and-javascript-now-in-print.html" />
        <link rel="replies" type="text/html" href="http://www.benrady.com/2011/06/continous-testing-with-ruby-rails-and-javascript-now-in-print.html" thr:count="1" thr:updated="2011-07-02T21:03:51-05:00" />
        <id>tag:typepad.com,2003:post-6a00e54fb013da8834015433620749970c</id>
        <published>2011-06-30T21:14:18-05:00</published>
        <updated>2011-06-30T21:14:18-05:00</updated>
        <summary>It's done! It's out. And I couldn't be happier. As part of writing writing Continous Testing: with Ruby, Rails, and JavaScript, I had the opportunity to talk to a lot of people about what Rod and I were doing, and...</summary>
        <author>
            <name>Ben Rady</name>
        </author>
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.benrady.com/">
<div xmlns="http://www.w3.org/1999/xhtml"><p><a href="http://pragprog.com/titles/rcctr/continuous-testing">It's done</a>! It's out. And I couldn't be happier.</p>

<p>As part of writing writing <em>Continous Testing: with Ruby, Rails, and JavaScript</em>, I had the opportunity to talk to a lot of people about what Rod and I were doing, and what they thought of it. Most of the people, once introduced to the idea, thought it was so obviously good that there just wasn't any reason not to follow this practice. By running your tests on every change, you create a tight feedback loop that makes it so much easier to find bugs and get a better understanding of what your code is doing. I'm really proud of what we've done with this book because I think the techniques we discuss in it will really open this practice up to a wide range of developers and projects. </p>
</div>
</content>



    </entry>
 
</feed><!-- ph=1 -->
