<?xml version="1.0" encoding="iso-8859-1" ?>
<rss version="2.0" 
   xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" 
   xmlns:html="http://www.w3.org/1999/html" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
<channel>
   <title>The Madstop</title>
   <link>http://www.madstop.com</link>
   <description>An administration, automation, and development blog</description>
   <language>en</language>
   <copyright>Copyright 2007 Luke Kanies</copyright>
   <ttl>60</ttl>
   <pubDate>Sat, 21 Jun 2008 14:18 GMT</pubDate>
   <managingEditor>luke@madstop.com</managingEditor>
   <generator>PyBlosxom http://pyblosxom.sourceforge.net/ 1.3.2 2/13/2006</generator>
<item>
   <title>Preparing for Velocity and the Puppet MiniConf</title>
   <guid isPermaLink="false">conference/preparing_for_velocity</guid>
   <link>http://www.madstop.com/conference/preparing_for_velocity.html</link>
   <description><![CDATA[
<p>I finally got access to my blog again (laziness combined well with the SSH key exploit to lock me out for a bit), and it's long past time I
posted an update.</p>
<p><a class="reference" href="http://stochasticresonance.wordpress.com/">Andrew</a> and I will be at <a class="reference" href="http://en.oreilly.com/velocity2008/public/content/home">Velocity</a> Monday and Tuesday, and I'll be giving a presentation there on Tuesday afternoon.  We then have to hurry downtown
to <a class="reference" href="http://www.cloudcamp.com/">CloudCamp</a>, and then Wednesday will be at <a class="reference" href="http://events.gigaom.com/structure/08/">Structure</a>.  <a class="reference" href="http://blog.hjksolutions.com/">Adam Jacob</a> says we should all be sure to attend the <a class="reference" href="http://radar.oreilly.com/archives/2008/05/ignite-velocity-submit-your-ta.html">Velocity Ignite!</a> on Monday night,
too.</p>
<p>Then, because hey, free time is for losers, Jay Aras is hosting a Puppet MiniConf on Thursday</p>
<p>Andrew has been working steadily on getting new Puppet <a class="reference" href="http://stochasticresonance.wordpress.com/2008/06/20/puppet-rising/">logos</a> going (you should see a new favicon on the <a class="reference" href="http://reductivelabs.com/trac/puppet/">Trac</a> site), and he promises to update our CSS
in time for the conference.</p>
<p>And, last but not least, we'll be showing up with fancy new Puppet t-shirts. We'll be trying to figure out over the course of the week how to
dole out shirts, so if you've got any good ideas, send me a note.</p>
<p>Anyway, I hope to see many of you over the course of the week, and I also hope to be updating far more often.</p>

]]></description>
   <category domain="http://www.madstop.com">/conference</category>
   <pubDate>Sat, 21 Jun 2008 14:18 GMT</pubDate>
</item>
<item>
   <title>Testing Cached Values</title>
   <guid isPermaLink="false">programming/testing_cached_values</guid>
   <link>http://www.madstop.com/programming/testing_cached_values.html</link>
   <description><![CDATA[
<p>I'm currently in the middle of the largest refactoring effort I've ever done, while simultaneously learning tons about
how to be a better developer.  I'm constantly feeling a bit overwhelmed, a bit behind the curve, and like someone's
going to look at my code one day and say, &quot;hey nimwit, you just pull this string here and suddenly 2/3 of your code just
goes away.&quot;</p>
<p>However, one thing I've really grokked recently is that if you're fighting your tools too much, you are on the wrong
track, and one way in which it seems I'm constantly fighting my tools is the combination of cached values and testing.</p>
<p>For instance, I have an <tt class="docutils literal"><span class="pre">HttpPool</span></tt> class that knows how to set up <tt class="docutils literal"><span class="pre">Net::HTTP</span></tt> instances with all of the SSL
information they need.  This class caches SSL information like the certificate and key, so that each connection doesn't
hit the disk for this info, which is obviously a pretty decent use of the cache.  This caching generally takes this
simple form:</p>
<pre class="literal-block">
def ssl_host
    unless defined?(&#64;ssl_host)
        &#64;ssl_host = Puppet::SSL::Host.new
    end
    &#64;ssl_host
end
</pre>
<p>Yes, you could just do <tt class="docutils literal"><span class="pre">&#64;ssl_host</span> <span class="pre">||=</span> <span class="pre">Puppet::SSL::Host.new</span></tt>, but I've gotten some weird behaviour out of that in the
past, and it also throws a warning for undefined variables.</p>
<p>So anyway, this works fine in unit tests; I test the caching, and I use mocks everywhere else.  When I get to
integration tests, though, it starts to really hurt, especially since I try not to do much mocking in my integration
tests.</p>
<p>For instance, say I've got two unrelated tests that do an ssl connection.  They each create some certificates, start a
daemon, and try to connect.  In this situation, the first one caches the ssl information, and the second one uses the
cached values instead of its own new certificate, and you get invalid certificates.</p>
<p>After talking to <a class="reference" href="http://www.rickbradley.com/">Rick Bradley</a> on #nashdl on IRC (gotta represent!), I've decided on at least an initial course of
action.  I'm going to create a module that provides both a caching and cache-clearing interface; anyone using cached
values would use this caching interface instead of caching the values themselves, and the module itself would give you a
single point of entry for clearing all caches on the system.</p>
<p>My first instinct was to create a Cache class or struct and keep a list of them in the caching module, so they can be
cleared as necessary, but my recent work with <a class="reference" href="/programming/caching_and_rest.html">TTLs</a> has made me realize that time-based concepts of cache dirtiness are
much better than actively cleaning.</p>
<p>So now, I'm thinking that the caching module will just have a timestamp, and only cached values created after that time
will be valid.  Before the Cache struct returns any values, it will always check that time, and it will know whether the
value it has is still good or should be discarded.</p>
<p>This keeps us from maintaining global lists of caches, and it also makes clearing caches insanely cheap -- just reset a
timestamp.  Given that Puppet already sometimes has onerous memory requirements, I also like that it makes the caches
themselves more likely to get garbage collected, since only the caching instance ever knows about the actual cache
itself.</p>
<p>So my new method would look something like this:</p>
<pre class="literal-block">
def ssl_host
    cache(:ssl_host) { Puppet::SSL::Host.new }
end
</pre>
<p>That bit with the block is something I just thought of; if we've got a value, it's not called, but if we need a value,
it's there for us.  Pretty sweet.</p>
<p>Now just to implement it.</p>

]]></description>
   <category domain="http://www.madstop.com">/programming</category>
   <pubDate>Wed, 07 May 2008 14:15 GMT</pubDate>
</item>
<item>
   <title>Jay and I converge on testing</title>
   <guid isPermaLink="false">ruby/jay_and_i_converge_on_testing</guid>
   <link>http://www.madstop.com/ruby/jay_and_i_converge_on_testing.html</link>
   <description><![CDATA[
<p>Those four people who have been reading this blog for a while know I've been struggling to think and program like <a class="reference" href="http://blog.jayfields.com/">Jay Fields</a>.  In particular,
he seems to have presented a few rules in the past that don't like to be used together:</p>
<ul class="simple">
<li><a class="reference" href="http://blog.jayfields.com/2007/06/testing-inline-setup.html">Inline setup code</a>: You apparently should not use <tt class="docutils literal"><span class="pre">before</span></tt> or <tt class="docutils literal"><span class="pre">setup</span></tt> blocks with your code; instead, you should
have all of the setup code in every method.</li>
<li><a class="reference" href="http://blog.jayfields.com/2007/04/ruby-mocks-and-stubs-using-mocha.html">Mocks instead of Stubs</a>: Here he claims that it's always better to use <tt class="docutils literal"><span class="pre">expects</span></tt> instead of <tt class="docutils literal"><span class="pre">stubs</span></tt>.</li>
<li><a class="reference" href="http://blog.jayfields.com/2008/01/testing-one-expectation-per-test.html">One expectation per test</a>: With only one expectation, you're only testing one feature at a time, and you're
guaranteed that each behaviour is tested separately.</li>
</ul>
<p>Now, let's do a simple combinatorial exercise, and put these three rules together:</p>
<ul class="simple">
<li>You should have all related code in your test</li>
<li>You should only use Mocks (<tt class="docutils literal"><span class="pre">expects</span></tt>), not Stubs (<tt class="docutils literal"><span class="pre">stubs</span></tt>)</li>
<li>You should only have on expectation (<tt class="docutils literal"><span class="pre">expects</span></tt>) per test</li>
</ul>
<p>It's pretty clear that, like the old saw about programming (&quot;All programs can be reduced to one line of code with a bug
in it&quot;), Jay is pointing us toward tests that can largely only be one line of code.  Yeah, I know sometimes setup
methods don't involve any mocking, but often they do.</p>
<p>And, since your tests can only be one line of code, they can't test very much, which means that all of your methods need
to <em>also</em> be one line of code, else they aren't testable. (Yes, I'm being a touch extreme here, but that is where the
arrow is pointed, anyway.)</p>
<p>You can see how this would kinda drive me bonkers.  Some local <a class="reference" href="http://ni.hili.st/">dev friends</a> have been trying to help me see the error
of my ways, mostly so my code would stop looking like such crap; I've learned a helluva lot in the last 8 months or so,
and most of it has actually made my code look more like Jay would recommend.  I will say it's blindingly obvious Jay is
doing internal development at enterprises, rather than developing as part of a consistent team producing software that
is distributed to the wider world.</p>
<p>But one can only go so far, and the three rules above, in combination, are just way too far.  I've often kind of
sputtered expasperatedly at Jay's posts, especially his announcement of his new testing tool, <a class="reference" href="http://blog.jayfields.com/2007/12/ruby-expectation-gem.html">expectations</a>.  Again,
I can kind of see where he's going with that, but you've got another thing coming if you think I'm using it, especially
given how happy (at least, relative to <tt class="docutils literal"><span class="pre">test/unit</span></tt>) I am with RSpec.</p>
<p>Also, I think it's just stupid having all setup code inline.  DRY (&quot;don't repeat yourself&quot;) is just as true in your test
code as anywhere else, and having a maintainable test code base is, IMO, <em>more</em> important than having your normal code
base be maintainable, because tests are kind of unnecessary.  If you have good, readable, maintainable tests, then
people who contribute will also contribute tests.  If your tests are all 50 lines long and have lots of repetition, then
1) you've got 5x the amount of code you should, which is wicked expensive, and 2) you've got so much code no one will
look at it.  Yay, never getting patches with tests in them.  My favorite example of this is <a class="reference" href="http://steve-yegge.blogspot.com/">Steve Yegge</a>'s rant
<a class="reference" href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html">Code's Worst Enemy</a>; he describes his 500k line Java project with no tests, which is a lot of code but much less code
than if it had tests.  I've experienced in Puppet that test code seems to be much harder to maintain that normal code
(although maybe it's just own crap test code, not normal test code), and having 5x test code than normal code would make
me just quit writing unit tests entirely.</p>
<p>So, I am absolutely overjoyed to announce that Jay has changed one of his rules:  He now recommends <a class="reference" href="http://blog.jayfields.com/2008/05/using-stubs-to-capture-test-essence.html">stubs over mocks</a>.
This is clearly just for setup code and such, but it's a big step.  He even goes into using <tt class="docutils literal"><span class="pre">stub_everything</span></tt>, which I
find is the only way to build tests that aren't fragile.  For instance, say you start with this code:</p>
<pre class="literal-block">
class MyClass
    def go
        start()
        finish()
    end
end

describe MyClass do
    before
        &#64;me = MyClass.new
        &#64;me.stubs(:start)
        &#64;me.stubs(:finish)
    end

    it &quot;should start when going&quot; do
        &#64;me.expects(:start)
        &#64;me.go
    end

    it &quot;should finish when going&quot; do
        &#64;me.expects(:finish)
        &#64;me.go
    end
end
</pre>
<p>Now you find you need a validation method, so you add this test:</p>
<pre class="literal-block">
it &quot;should validate when going&quot; do
    &#64;me.expects(:validate)
    &#64;me.go
end
</pre>
<p><strong>Update</strong>: Fixed code to actually call <tt class="docutils literal"><span class="pre">&#64;me.go</span></tt> in the <tt class="docutils literal"><span class="pre">validate</span></tt> test.</p>
<p>Oops.  Now your single test passes, but your two old tests break, because you were only stubbing <tt class="docutils literal"><span class="pre">start</span></tt> and
<tt class="docutils literal"><span class="pre">finish</span></tt>, instead of using <tt class="docutils literal"><span class="pre">stub_everything</span></tt>.  Your setup code needs to be modified to take this new call into
account (or, if you're Jay, you need to modify every test in your suite; yay).  This comes up <em>constantly</em>.  If you
specifically mock or stub methods during setup, then you are almost guaranteed to have cascading failures when you
expand your code.</p>
<p>Anyway, the point is, if I tried to follow Jay's rules, then the above trivial change -- I add one line of code to a
<em>very</em> simple method -- would result in me adding a test for that line, plus at least one line of code in every other
test in that suite.  Instead, if I use <tt class="docutils literal"><span class="pre">stub_everything</span></tt>, then I add my new test and I'm done. (Well, kind of; notice
I'm not actually testing the order of the method calls, which is actually pretty tough.)</p>
<p>My recommendation is to read Jay, since he's clearly thinking and talking about aspects of testing that not many others
are, but read him with a skeptical eye, and be willing to say &quot;That's just nuts!&quot; and write your own relatively
abstracted test code.  And if you're working with people who can't think to look at their setup code when a test fails,
then you need to find a different job.</p>

]]></description>
   <category domain="http://www.madstop.com">/ruby</category>
   <pubDate>Tue, 06 May 2008 08:23 GMT</pubDate>
</item>
<item>
   <title>Ruby has a distribution problem</title>
   <guid isPermaLink="false">ruby/ruby_has_a_distribution_problem</guid>
   <link>http://www.madstop.com/ruby/ruby_has_a_distribution_problem.html</link>
   <description><![CDATA[
<p>I've been doing a better job of reading development books recently (e.g., <a class="reference" href="http://www.powells.com/biblio/62-9780321125217-1">Domain Driven Design</a>), and something has
really begun to stick out at me.  There seems to be a split between those developers who write software that is expected
to run in one place and those who write software that is expected to run in many places.</p>
<p>If you, as a developer, know that your software will really only be installed at a single customer (whether that
customer is your employer, a consulting client, or whatever), then your life is drastically easier -- you don't usually
have to worry about cross-platform issues, and you don't have to worry about different users having different needs,
because you only have one user.</p>
<p>Obviously there's no inherent problem with having the simpler life of a developer with only one user, but it seems to me
that the Ruby community is, as a group, largely adopting that perspective as the default.  This is worrying to me,
because I'm building an application that I expect to be installed in thousands of locations (in fact, it's probably
already installed in thousands of locations).  I'd like to take as much advantage of existing Ruby code as possible, but
it's not exactly easy.</p>
<p>For example, <a class="reference" href="http://www.rubygems.org/">rubygems</a> (probably my least favorite ruby software of all time) basically require that you <em>always</em> try to
load them, because their design stupidly requires that you know whether a given piece of software is installed via
rubygems or some other mechanism.  For instance, if you've installed the <a class="reference" href="http://reductivelabs.com/trac/facter/">Facter</a> gem, then this code doesn't work:</p>
<pre class="literal-block">
ruby -rfacter -e 'Facter.to_hash'
</pre>
<p>Instead, you have to do this:</p>
<pre class="literal-block">
ruby -rubygems -rfacter -e 'Facter.to_hash'
</pre>
<p>The reason is that rubygems installs in a location that Ruby doesn't search by default.  The reason for that is that
apparently this one guy, somewhere, wanted to have multiple versions of a given package installed at once.  Who wants
this?  Let's just say it's not the guys who are distributing hundreds and thousands of copies of their software.</p>
<p>The truth is, most Rubyists don't even seem to use gems this way -- they tend to create a <tt class="docutils literal"><span class="pre">vendor</span></tt> subdirectory in
their project, and then install their gems there.  This is a clear example of how little they expect to have their
projects distributed.  These gems might be compiled, they might conflict with installed software, they might <em>require</em>
installed software -- you have no idea, because it's an entirely separate repository of packages.</p>
<p>This is basically anathema to how I think about management, yet it's the standard, recommended practice in the Rails
community, because it makes it easy to &quot;guarantee&quot; behaviour in a given environment.  Of course, your guarantee is only
good if no one ever tries to run the software anywhere except an exact duplicate of where you run it.</p>
<p>I tried to have a conversation about this at the <a class="reference" href="http://www.rubyhoedown.com/">Ruby Hoedown</a> last year -- my claim was it was difficult to turn a
Rails project into a native package, especially with the tendency toward requiring all kinds of random gems.  Quite a
few people kind of stared blankly at me and said, multiple times, &quot;I just put it in vendor.&quot;  Since then, this has
become my go-to phrase for describing the Ruby way of solving distribution problems: &quot;I just put it in vendor.&quot;  I keep
waiting for someone to try to put their kernel or web browser in <tt class="docutils literal"><span class="pre">vendor</span></tt>:  &quot;We only support the Firefox copy in
<tt class="docutils literal"><span class="pre">vendor</span></tt>, sorry.&quot;</p>
<p>I don't know if other communities are any better at this.  From what I can tell, this is basically how the Java
community behaves, too.  They have pathologically bad distribution systems, and as a language it seems to be most
influenced by consulting shops developing huge, worthless software projects for large enterprises, rather than
developing distributed applications that will be installed in thousands of locations.</p>
<p>I'd like to think that Puppet would have some counter-affect to this.  It's one of the largest and most sophisticated
publicly available Ruby projects, it's already installed in at least hundreds and probably thousands of places, and it
does a pretty good job of working nearly everywere.  However, I keep getting blank stares when I talk about this with
other Rubyists, half the time I'm called a troll for even bringing it up, and when I explain why Puppet exists to
most Rubyists, they just say, &quot;I just put it in vendor&quot;, or, maybe, &quot;Why not just use Capistrano?&quot;  To that I ask, how
do you install Capistrano, but you know what they say to that.</p>
<p>I think Rails is a big part of the problem.  Rails is clearly created by a company that will never distribute its
software, and the Rails philosophy is again almost pathologically opposed to the idea of turning your software into a
package.  Imagine trying to make a Rails project LSB compliant -- your <tt class="docutils literal"><span class="pre">database.yaml</span></tt> file would need to be in
<tt class="docutils literal"><span class="pre">/etc</span></tt>, your <tt class="docutils literal"><span class="pre">log</span></tt> directory would need to be in <tt class="docutils literal"><span class="pre">/var</span></tt>, and your actual code would need to be in <tt class="docutils literal"><span class="pre">/usr</span></tt>.  There
went all of your fancy Rails &quot;convention over configuration&quot;, and you're suddenly fighting Rails instead of using it,
and everyone you ask for help just tells you to &quot;put it in vendor&quot;.</p>
<p>I'm looking at creating a new application that I'm planning on distributing, and one of my big goals is to be able to
distribute the core in one package and various additional pieces of functionality as separate packages.  I'll need to
simultaneously support as many of my customer platforms as I can and provide a consistent operating environment for my
packages.  The <em>only</em> way to do this is to have supported operating environments with well-defined dependencies, such as
you can almost trivially build in Debian or Red Hat.</p>
<p>For those of you who are thinking, &quot;you could just put it in vendor&quot;, or &quot;you could at least use gems&quot;, No, I couldn't.
Take a trivial example:  Say I want to use <a class="reference" href="http://oss.oetiker.ch/rrdtool/">RRD</a> support in my application (which is likely, in this case).  There is
Ruby support for RRD, but not in Gem form.  Even if there were a gem, though, it would require a native RRDTool package,
and, of course, Gems can't specify dependencies on native packages, so I'd be telling my customers, &quot;well, install X
gems and Y packages&quot;.</p>
<p>Instead, if I use native packages (say, those for Debian and Red Hat, to cover most cases), I can define clear
dependencies for all cases.  I know Debian provides everything I need, and in the rare case it doesn't, I can provide my
own <tt class="docutils literal"><span class="pre">apt</span></tt> repository (and the same for yum).  Gems, on the other hand, can really only do Ruby stuff.  No, I don't
actually want to put <tt class="docutils literal"><span class="pre">glibc</span></tt> in <tt class="docutils literal"><span class="pre">vendor</span></tt>, thanks.</p>
<p>I don't see a solution to this, other than getting more Rubyists distributing their software, but I'd really like to see
this issue begin to be approached by the community.  I feel like a wolf howling in the wilderness at this point, and if
often feels like I'm fighting against my community in order to produce software that hundreds or thousands of people
will <em>install</em>, as opposed to just use over the web.</p>

]]></description>
   <category domain="http://www.madstop.com">/ruby</category>
   <pubDate>Mon, 05 May 2008 22:13 GMT</pubDate>
</item>
<item>
   <title>Git branch in your bash prompt</title>
   <guid isPermaLink="false">tools/git_branch_in_your_bash_prompt</guid>
   <link>http://www.madstop.com/tools/git_branch_in_your_bash_prompt.html</link>
   <description><![CDATA[
<p><a class="reference" href="http://b.logi.cx/">Kevin Barnes</a> has <a class="reference" href="http://b.logi.cx/2008/5/5/git-bash-awk-crazy-delicious">posted</a> his mechanism for getting the current branch of the git repository into his bash prompt.</p>
<p>He mentions color in his article, and it turns out I'm the person who added the color, so I figured I'd post my version.</p>
<p>Here are the functions I have:</p>
<pre class="literal-block">
git_current_branch()
{
  git branch 2&gt;/dev/null | sed -n '/^\*/ s/^\* //p'
}

git_display()
{
  br=$(git_current_branch)
  if [ -n br ]; then
      echo $br | BRANCH=&quot;$br&quot; GIT_COLOR=$(git_color) awk '{if ($1) { print ENVIRON[&quot;GIT_COLOR&quot;] ENVIRON[&quot;BRANCH&quot;] &quot; &quot; } }'
  fi
}

git_color()
{
    git status 2&gt;/dev/null | grep -c : | awk '{if ($1 &gt; 0) { print ENVIRON[&quot;ORANGE&quot;] } else { print ENVIRON[&quot;PINK&quot;] } }'
}
</pre>
<p>And then here's my prompt:</p>
<blockquote>
title=&quot;033]0;h:W007&quot;
PS1=&quot;$title[$(git_display)$GREENw$NOCOLOR]nu&#64;h(&quot;'$?'&quot;) $ &quot;</blockquote>
<p>First, the <tt class="docutils literal"><span class="pre">git</span></tt> bits.  As Kevin mentions, I color the branch name; I use orange if I've got modified files, and pink if I don't
(these are names that I map elsewhere to terminal codes).  The three functions provide the three, um, functions:  See what branch
I'm on, see whether there are uncommitted files, and colorize the branch name.</p>
<p>Now, the bash bits.</p>
<p>First, you'll notice I have a multi-line prompt.  I first started this when I switched to a color prompt, because for a while there bash
didn't like the hidden characters that add color.  I got to choose between a multi-line prompt, or a prompt that wrapped in broken ways.
Since I really only wanted color in the path, I put that on the upper line, avoiding <em>most</em> of the wrapping problems.  It was worth it,
because (especially when I was still a sysadmin by trade) having color, almost any color, in the prompt makes it easy to pick out my
commands from command output.</p>
<p>Now that I've had my prompt this way for about 4 years, I'm pretty fond of it.  I think the bash wrapping problems are mostly fixed now,
but I'm keepin git.</p>
<p>The <tt class="docutils literal"><span class="pre">$title</span></tt> sets the terminal title (which is <em>slightly</em> useful).</p>
<p>So, that's how I add the git branch, colored by whether I have uncommitted files, to my prompt, with a bit more prompt info thrown
in for kicks.</p>

]]></description>
   <category domain="http://www.madstop.com">/tools</category>
   <pubDate>Mon, 05 May 2008 00:59 GMT</pubDate>
</item>
<item>
   <title>Reductive Labs should fill out the Little 4</title>
   <guid isPermaLink="false">industry/reductive_labs_should_fill_out_the_little_4</guid>
   <link>http://www.madstop.com/industry/reductive_labs_should_fill_out_the_little_4.html</link>
   <description><![CDATA[
<p><a class="reference" href="http://www.redmonk.com/cote/">Michael Cote</a> and <a class="reference" href="http://www.johnmwillis.com/">John Willis</a> have been talking for a while about the <a class="reference" href="http://www.redmonk.com/cote/2007/01/16/open-platforms-in-systems-management/">Little 4</a> in management software, and it
looks like <a class="reference" href="http://qlusters.com/">Qlusters</a> is <a class="reference" href="http://blogs.the451group.com/opensource/2008/04/10/qlusters-waves-goodbye-to-openqrm/">no longer</a> on the list.</p>
<p>I'd love to be able to comfortably say that Reductive Labs deserves to fill that fourth slot (you can have <a class="reference" href="http://www.krisbuytaert.be/blog/node/649">your say</a>
too).  The truth is, of course, that all of those companies are far larger than Reductive Labs, and they've all
successfully gotten investment while we have not (although we haven't tried all <em>that</em> hard).  The products of the
companies are pretty dissimilar, too -- they're mostly more focused on monitoring rather than what I would call
management, as far as I can tell.</p>
<p>On the other hand, Puppet has a lot of traction, and is a clear leader in its space.  We've been profitable since almost the beginning (which
is to say, profitable enough to pay my meagre wages), and we've got a great and growing community.  Now that <a class="reference" href="http://stochasticresonance.wordpress.com/">Andrew
Shafer</a> has joined the company full-time as a partner, I do think we're going to start growing, and it's well-timed in
terms of how the community is developing.</p>
<p>I do hope we grow this year, but I don't really know how we will.  I'm still considering how hard we should be seeking
investment, but it seems that VCs are pretty uninterested in infrastructure (or maybe they're just uninterested in me).
Really, I'm hoping I can just get a big enough customer base that Andrew and I can build a bigger development team and
start doing some of the almost-obvious but really interesting projects to enhance the Puppet ecosystem, like change
control applications.</p>
<p>But the summary is, I want to deserve to be in the Little 4, and I think Puppet is popular enough that we just might,
but there's still lots more to do.</p>

]]></description>
   <category domain="http://www.madstop.com">/industry</category>
   <pubDate>Mon, 21 Apr 2008 20:27 GMT</pubDate>
</item>
<item>
   <title>Closing the Whisky Experiment</title>
   <guid isPermaLink="false">closing_the_whisky_experiment</guid>
   <link>http://www.madstop.com/closing_the_whisky_experiment.html</link>
   <description><![CDATA[
<p>It's been a bit more than a month since I started my <a class="reference" href="http://www.madstop.com/whisky_in_the_name_of_science.html">Double Blind Whisky Taste Test</a>, and I've decided it's time to call it.
I've drunk a scarily large amount of the whisky, but science is a harsh mistress and she will not be denied.  Those of
you who are sitting at home complaining that I haven't fixed your bug, it's because I was drunk from too much
experimentation.</p>
<p>I've posting my reviews to <a class="reference" href="http://twitter.com/puppetmasterd">Twitter</a>, which in some ways adds a third blindness:  I didn't know how I reviewed a given Scotch previously.</p>
<p>I'm writing this having not yet looked at the key that will tell me which Scotch is which.  Here are my reviews so far
(using my arbitrary decanter names).  I'm actually taking a small drink of each as I write, just to remind myself and
do one last review.  These reviews are in order of perceived strength, so that I'm going from weakest to strongest.</p>
<p>My comments will also try to mention what I would do with these whiskies; this is because I've still got decanters with
a lot of whisky in them, and really, I probably won't drink them all straight, which is all I would normally do with a
single malt.</p>
<p>My primary goal in this review was to find that single peaty Scotch that I could put in my liquor cabinet (currently
virtual, since the liquor is kind of scattered wherever there is storage).</p>
<ul>
<li><p class="first"><em>Teardrop</em>: Very drinkable and very smooth, but relatively mild.  It almost doesn't belong in this review.  Once I
have closed the experiment, I look forward to comparing it to Macallan, which is my old stand-by in terms of smooth
Scotch.  A little bit of peat, some harshness if you aren't careful, and just a bit of roundness.  It's like all the
edges are filed off and nothing really stands out.  I expect this is a great Scotch if you're not drinking it near
anything else, but near the others, it seems weak.  It's almost a Scotch for people who don't drink Scotch.</p>
<p>I like it, but it's not peaty enough to be considered a great peaty whisky.</p>
</li>
<li><p class="first"><em>Oval</em>: This one definitely has some peat in it, but it's got a hint of sourness that I don't really like (that's sour
as in &quot;something went sour&quot; as opposed to &quot;puckery&quot;).  This is apparently a consistent review, since I've mentioned
that in my twitter microreviews, too.  I expect that this would make a great whisky sour, but you would always want to
hide the whisky's own sour, rather than focusing on it.  Hopefully it would meld with the citrus, rather than having
some sort of weird sour harmonic.</p>
<p>At least this one's peaty, and it's got an overall good flavour.  I wouldn't recommend it to most people, though,
because of the sour note.  I do remember drinking this multiple times without really noticing the sour, for what it's
worth.</p>
</li>
<li><p class="first"><em>The D</em>:  <a class="footnote-reference" href="#id2" id="id1" name="id1">[1]</a> This is definitely my favorite.  It's got peat, a bit of spice, no real harshness unless you snort it,
and none of the sourness of the oval.  It has an almost mustiness to it, like a good blue cheese.  It's really an
even, peaty whisky; drinkable neat, but strong.  It should mix well if you wanted to, given how much flavour it has,
and go well in soda or with ice, but it deserves to be neat, or maybe on ice to keep the fumes down.</p>
</li>
<li><p class="first"><em>Square</em>: Very spicy, almost with a Bourbon spice, but quite harsh, also.  Strangely, there isn't a lot of other flavour to
it.  There's some peat to it (I expect that's what adds the spice), but the harshness stands out so much that I'm not
real fond of this whisky.  I'm not even convinced it would taste that good with soda (which is often how I drink my
bourbon), since it doesn't have much depth.</p>
</li>
</ul>
<p>Okay, so now we know what I think about each of the whiskies, it's time to get the key out and see what is what.  First,
though, I will give my guesses as to what is what.  Here's my estimate:</p>
<ul class="simple">
<li><em>Laphroaig</em>: Square</li>
<li><em>Teardrop</em>: Caol Ila</li>
<li><em>Ardbeg</em>: Oval</li>
<li><em>Lagavulin</em>: The D</li>
</ul>
<p>And now, without further ado, here's the real key:</p>
<ul class="simple">
<li><em>Laphroaig</em>: Oval</li>
<li><em>Teardrop</em>: Caol Ila</li>
<li><em>Ardbeg</em>: Square</li>
<li><em>Lagavulin</em>: The D</li>
</ul>
<p>So, I got two correct but mixed two of them.  The clear winner in the &quot;best peaty Islay malt&quot; category is Lagavulin,
which is unfortunate, since it's about $20 more per bottle than any of the others (assuming you can find Caol Ila, which
I had to buy at the Duty Free in Melbourne).  The Caol Ila gets an honorable mention as the easiest to drink.</p>
<p>Looks like I've been harshing on the Ardbeg this whole time, and it's the Laphroaig that has the sourness I didn't
particularly like.</p>
<p>And with that, the experiment closes.  Now I can finally drink some of the Caol Ila 18yr I have -- I couldn't drink it
while the experiment was on, since it would likely have clued me into which decanter had the 12yr.</p>
<p>In the name of Science (and great whisky),
Luke</p>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1" name="id2">[1]</a></td><td>This decanter has a square bottom and a kind of oval top, so it looks kind of like a D sitting on its back.
Really, though, it gets its name from the movie <tt class="docutils literal"><span class="pre">8</span> <span class="pre">Mile</span></tt> -- I have a friend from Detroit who said it was an
accurate portrayal of Detroit, and ever since I've harassed him about how Eminem calls the city &quot;The D&quot;.</td></tr>
</tbody>
</table>

]]></description>
   <category domain="http://www.madstop.com"></category>
   <pubDate>Sun, 13 Apr 2008 21:18 GMT</pubDate>
</item>
<item>
   <title>ArsTechnica Launches Forum on Large-Scale IT</title>
   <guid isPermaLink="false">industry/arstechnica_launches_forum_on_largescale_it</guid>
   <link>http://www.madstop.com/industry/arstechnica_launches_forum_on_largescale_it.html</link>
   <description><![CDATA[
<p>(by Luke)
<a class="reference" href="http://arstechnica.com/">ArsTechnica</a>, my favorite tech news site, has just <a class="reference" href="http://arstechnica.com/news.ars/post/20080409-ars-launches-the-server-room-for-large-scale-it-discussion.html">announced</a> the launch of a forum dedicated to the discussion
of large-scale IT:</p>
<blockquote>
The forum has been in beta for a few weeks, and already there are some great
discussions happening. We envision The Server Room as a place to discuss IT
topics that don't already have a dedicated forum, and are of an IT nature.
Users are already talking about virtualization, storage, disaster recovery, and
systems design. IT hardware discussion is appropriate as a function of the
plan.</blockquote>
<p>So go join the <a class="reference" href="http://episteme.arstechnica.com/eve/forums/a/frm/f/833003030931">Server Room</a> and tell 'em how great Puppet is.</p>

]]></description>
   <category domain="http://www.madstop.com">/industry</category>
   <pubDate>Wed, 09 Apr 2008 13:11 GMT</pubDate>
</item>
<item>
   <title>Mountain West Ruby Conference</title>
   <guid isPermaLink="false">mountain_west_ruby_conference</guid>
   <link>http://www.madstop.com/mountain_west_ruby_conference.html</link>
   <description><![CDATA[
<p>(By Drew)</p>
<p>I've been meaning to post this for a while, but we didn't have a good way to make this a multi-author blog.  (We still don't, which is only slightly less lame than the fact that I haven't put anything up about the conference)</p>
<img alt="http://www.reductivelabs.com/images/mtnwestrubyconf-attendee-badge-170.png" src="http://www.reductivelabs.com/images/mtnwestrubyconf-attendee-badge-170.png" />
<p>I spent the weekend before last at the Mountain West Ruby Conference (March 28-29).</p>
<p>This was the first language centric conference I have attended and I would recommend getting involved to anyone who wants to expand their understanding of Ruby and programming.</p>
<p>These conferences aren't going to help someone find all the answers, but they will help you start asking the right questions, and you couldn't beat the price of MWRC. $100 for a t-shirt, 2 lunches, 2 full days of talks, plus 2 party/hackfests with a fridge packed full of redbull and a room packed with passionate programmers.</p>
<p>Just doesn't get much better than that. . .</p>
<p>The speakers topics ranged from whimsical to deep magic. Some of my favorites were Giles Bowkett on metprogramming/code generation(who had everyone monkey patching sombreros into the presentations), the keynote by Jim Weirich, and Patrick Farley on Ruby internals. The most practical presentation, at least for me and Puppet, was Philippe Hanrigou's talk on using GDB and DTrace to troubleshoot running processes.</p>
<p>There are some excellent resources on Phillipe's <a class="reference" href="http://www.ph7spot.com/">website</a>. Anyone interested in getting insight into running Ruby processes should take advantage of what he has available.</p>
<p>All the speakers are <a class="reference" href="http://mwrc2008.confreaks.com/">online</a>. (Thanks Confreaks and the sponsors)</p>
<blockquote>
These aren't the $10 dollar burritos you are looking for</blockquote>
<img alt="http://www.reductivelabs.com/images/sombrero.jpg" src="http://www.reductivelabs.com/images/sombrero.jpg" />

]]></description>
   <category domain="http://www.madstop.com"></category>
   <pubDate>Tue, 08 Apr 2008 00:33 GMT</pubDate>
</item>
<item>
   <title>Checking whether classes have been evaluated</title>
   <guid isPermaLink="false">puppet/checking_whether_classes_have_been_evaluated</guid>
   <link>http://www.madstop.com/puppet/checking_whether_classes_have_been_evaluated.html</link>
   <description><![CDATA[
<p>Another snippet I used for testing.</p>
<p>Bug <a class="reference" href="http://reductivelabs.com/trac/puppet/ticket/1165">#1165</a> requests the ability to check for whether a class exists, but we've already got that:</p>
<pre class="literal-block">
class yay {
    notify { &quot;This is a test&quot;: }
}

class other {
    if defined(Class[yay]) {
        notify { &quot;Defined works just fine&quot;: }
    }
}

include yay, other
</pre>
<p>Prints:</p>
<pre class="literal-block">
notice: This is a test
notice: Defined works just fine
</pre>
<p>Works for me. :)</p>

]]></description>
   <category domain="http://www.madstop.com">/puppet</category>
   <pubDate>Thu, 03 Apr 2008 09:34 GMT</pubDate>
</item>
</channel>
</rss>
