<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>serialized.net</title>
	<atom:link href="http://serialized.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://serialized.net</link>
	<description>An ongoing expression of fascination burnout</description>
	<lastBuildDate>Sat, 02 Jan 2010 00:09:48 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using custom functions in Puppet templates</title>
		<link>http://serialized.net/2010/01/using-custom-functions-in-puppet-templates/</link>
		<comments>http://serialized.net/2010/01/using-custom-functions-in-puppet-templates/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 00:09:48 +0000</pubDate>
		<dc:creator>Joshua Barratt</dc:creator>
				<category><![CDATA[Puppet]]></category>

		<guid isPermaLink="false">http://serialized.net/?p=353</guid>
		<description><![CDATA[This eventually required a support ticket to figure out, so I&#8217;m documenting it here in case it&#8217;s useful to others.
The problem: You have a puppet function you find useful. At this point custom functions are really easy to create and distribute via modules so there&#8217;s really no reason not to be using them. However, you [...]]]></description>
			<content:encoded><![CDATA[<p>This eventually required a support ticket to figure out, so I&#8217;m documenting it here in case it&#8217;s useful to others.</p>
<p>The problem: You have a puppet function you find useful. At this point custom functions are <a href="http://reductivelabs.com/trac/puppet/wiki/PluginsInModules">really easy to create and distribute via modules</a> so there&#8217;s really no reason not to be using them. However, you want to use the result of a function in your templates.</p>
<p>A real-world example of this is sharing authentication information. (For example, crypted password hashes. Plain text, as always, would be evil no matter where it was living.)<br />
You really have 3 choices:</p>
<ul>
<li>Coding it right into your puppet code and checking that into your version control system</li>
<li>Not distributing that information with puppet</li>
<li>Using puppet to distribute the information, but store it outside of your puppet modules somehow.</li>
</ul>
<p>We chose the third way, and store this kind of information in YAML files outside the puppet modules tree.<br />
Anyway. So we want to access this info inside a template.</p>
<p>Assume you have a function called &#8216;get_extdata&#8217;.<br />
You normally call from your &#8216;.pp&#8217; manifests with something like</p>
<pre class="brush: ruby;">
$data = get_extdata('mymodule', 'path:to:data')
</pre>
<p>You can make a call like that from your template by doing this wonderful fragment of magic-wand-waving to get this function accessible:</p>
<p>In <b>mytemplate.erb</b>:</p>
<pre class="brush: plain;">
&lt;% Puppet::Parser::Functions.autoloader.loadall %&gt;
Now you can use the 'scope' variable to get at your function.
This is the equivalent of the call get_extdata('mymodule',  'path:to:data'):
&lt;%= scope.function_get_extdata('mymodule',  'path:to:data') %&gt;
</pre>
<p>This works like a charm, and means you don&#8217;t have to create a bunch of variables that you don&#8217;t really need before you load the template.</p>
<p>So if you were creating an .htpasswd style file with puppet, you could do</p>
<p>In your <b>init.pp</b></p>
<pre class="brush: ruby;">
$users = ['steve', 'paul', 'stu']
</pre>
<p><b>htpasswd.erb</b>:</p>
<pre class="brush: plain;">
&lt;% Puppet::Parser::Functions.autoloader.loadall %&gt;
&lt;% users.each do |user| -%&gt;
&lt;%= user %&gt;:&lt;%= scope.function_get_extdata('authmodule',  user) %&gt;
&lt;% end -%&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://serialized.net/2010/01/using-custom-functions-in-puppet-templates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updated &#8220;Inbox Zero with Mail.app&#8221; technique</title>
		<link>http://serialized.net/2009/12/updated-inbox-zero-with-mail-app-technique/</link>
		<comments>http://serialized.net/2009/12/updated-inbox-zero-with-mail-app-technique/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 17:37:13 +0000</pubDate>
		<dc:creator>Joshua Barratt</dc:creator>
				<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://serialized.net/?p=344</guid>
		<description><![CDATA[Back in March, I wrote about my technique for implementing Inbox Zero with Mail.app.
Since then, the world has changed. I&#8217;ve upgraded to Snow Leopard, and Quicksilver has essentially stopped working out for me. (I&#8217;ve been trying to keep it up to date, and sometimes it kind of works, but my confidence levels are really low.) [...]]]></description>
			<content:encoded><![CDATA[<p>Back in March, I wrote about my <a href="http://serialized.net/2009/03/my-approach-to-inbox-zero-with-mailapp/">technique for implementing Inbox Zero with Mail.app</a>.</p>
<p>Since then, the world has changed. I&#8217;ve upgraded to Snow Leopard, and Quicksilver has essentially stopped working out for me. (I&#8217;ve been trying to keep it up to date, and sometimes it kind of works, but my confidence levels are really low.) On the other hand, I&#8217;m loving me some <a href="http://code.google.com/p/qsb-mac/">Google Quick Search Box</a> (a new project from the <a href="http://www.cultofmac.com/quicksilver-is-sort-of-dead-long-live-google-quick-search-box/6986">original creator of Quicksilver</a>). The only feature that I still wanted Quicksilver for was triggers. And until today, I was still running it for trigger support to implement my Inbox Zero trick.</p>
<p>And then triggers broke when I upgraded it. And I&#8217;m out.</p>
<p>So here&#8217;s how to get Inbox Zero magic in Mail.app using only tools native to Snow Leopard.</p>
<p>First, launch Automator and create a new Service workflow.<br />
<img src="http://serialized.net/wp-content/uploads/2009/12/Automator_select_service.jpg" alt="Automator Create a new Service Workflow" title="Automator Create a new Service Workflow" width="556" height="517" class="aligncenter size-full wp-image-345" /></p>
<p>Select &#8220;Utilities&#8221; and then drag in &#8220;Run Applescript&#8221; to the window on the right.</p>
<p><img src="http://serialized.net/wp-content/uploads/2009/12/automator-drag-run-applescript.jpg" alt="Automator: Run Applescript" title="Automator: Run Applescript" width="532" height="350" class="aligncenter size-full wp-image-346" /></p>
<p>Fill in your applescript, replacing only the center &#8220;comment&#8221; block &#8212; leave the other autogenerated lines there.</p>
<p>The core code again, (tweak to fit your accounts and archive mailbox names)</p>
<pre class="brush: plain; light: true;">
tell application &quot;Mail&quot;
	set theSelectedMessages to selection
	set myAccount to &quot;zimbra&quot;
	set myMailbox to &quot;Archive&quot;
	repeat with theMessage in theSelectedMessages
		move theMessage to mailbox myMailbox of account myAccount
	end repeat
end tell
</pre>
<p>It should look something like this:<br />
<img src="http://serialized.net/wp-content/uploads/2009/12/automator_archive.jpg" alt="Automator: Archive Applescript" title="Automator: Archive Applescript" width="586" height="490" class="aligncenter size-full wp-image-349" /></p>
<p>And that&#8217;s it! Save it, and give it a name you&#8217;ll remember. (I chose &#8220;Archive Selected Mail.&#8221;)</p>
<p>Now it&#8217;s actually in Mail&#8217;s Menu (under &#8216;Services&#8217;) and we can use the built in OSX hotkey support to launch it.</p>
<p>Go to the System Preferences Menu, click &#8220;Keyboard Shortcuts&#8221;, and add one for the menu item you created. (It needs to be the same exact name you saved your service as.)</p>
<p><img src="http://serialized.net/wp-content/uploads/2009/12/Keyboard-Shortcuts-Archive-Mail.jpg" alt="Keyboard Shortcuts: Archive Mail" title="Keyboard Shortcuts: Archive Mail" width="708" height="637" class="aligncenter size-full wp-image-350" /></p>
<p>Badda bing. Feature complete, and I can (sadly) retire Quicksilver forever. This technique should be extensible to all kinds of other cases when you want to add new features to applications, for access either through the menus or with hot keys.</p>
]]></content:encoded>
			<wfw:commentRss>http://serialized.net/2009/12/updated-inbox-zero-with-mail-app-technique/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Launching new specialized blog: ArduinoCollective.com</title>
		<link>http://serialized.net/2009/11/launching-new-specialized-blog-arduinocollective-com/</link>
		<comments>http://serialized.net/2009/11/launching-new-specialized-blog-arduinocollective-com/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 22:17:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Ramble]]></category>

		<guid isPermaLink="false">http://serialized.net/?p=342</guid>
		<description><![CDATA[My friend Nate and I have launched a new joint blog to record our electronics hacking projects: the Arduino Collective.
Subscribe over there if you&#8217;re interested in that kind of thing.
]]></description>
			<content:encoded><![CDATA[<p>My friend <a href="http://endot.org" rel="friend">Nate</a> and I have launched a new joint blog to record our electronics hacking projects: the <a href="http://arduinocollective.com" rel="me">Arduino Collective</a>.</p>
<p>Subscribe over there if you&#8217;re interested in that kind of thing.</p>
]]></content:encoded>
			<wfw:commentRss>http://serialized.net/2009/11/launching-new-specialized-blog-arduinocollective-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Great WordPress Plugin: WP Widget Cache</title>
		<link>http://serialized.net/2009/10/great-wordpress-plugin-wp-widget-cache/</link>
		<comments>http://serialized.net/2009/10/great-wordpress-plugin-wp-widget-cache/#comments</comments>
		<pubDate>Sun, 25 Oct 2009 05:26:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://serialized.net/?p=333</guid>
		<description><![CDATA[Using WP Widget Cache, I improved my site load time by about 600% by just starting to cache the widgets.
Here are some screenshots from my strace-based &#8216;magic profiler&#8217; (which I still promise to talk more about later.)
It lets you attach to a process which is about to render your website, and then trace all the [...]]]></description>
			<content:encoded><![CDATA[<p>Using <a href="http://wordpress.org/extend/plugins/wp-widget-cache/">WP Widget Cache</a>, I improved my site load time by about 600% by just starting to cache the widgets.</p>
<p>Here are some screenshots from my strace-based &#8216;magic profiler&#8217; (which I still promise to talk more about later.)<br />
It lets you attach to a process which is about to render your website, and then trace all the interactions it has with the underlying system while it renders it.</p>
<p>That includes network traffic, file server traffic, DNS resolver lookups &#8212; everything your app does to communicate to the outside world. The timing is always going to look slower than normal (at least a bit) as the tracing does impose some overhead, but it&#8217;s relatively pretty accurate.</p>
<p>Here&#8217;s what I saw right after telling WP Widget Cache to clear the caches.</p>
<p><img class="size-full wp-image-334 alignnone" title="With a freshly cleaned Widget cache" src="http://serialized.net/wp-content/uploads/2009/10/serialized_net_cleared_cache.jpg" alt="With a freshly cleaned Widget cache" width="348" height="269" /></p>
<p>And here is what I saw on the second hit:</p>
<p><img class="size-full wp-image-336 alignnone" title="With WP Widget Cache working like it should" src="http://serialized.net/wp-content/uploads/2009/10/serialized_net_widgets_cached.jpg" alt="With WP Widget Cache working like it should" width="303" height="188" /></p>
<p>I have widgets to load Flickr, (the entry with &#8216;flickr&#8217; in it) delicious bookmarks, (the yahoo one) and Twitter. (The naked IP. Apparently they don&#8217;t like PTR records.) Those three external calls dominated my total time to generate the page. Now, it&#8217;s down to a very quick MySQL lookup and a chatty conversation with a fileserver.</p>
<p>One feature I especially appreciate is the ability to tune cache times per widget. If I want new Flickr photos to be available hourly, sure. If my tweets need to be there within 5 minutes, not a problem. And because the widgets are there every time anyone uses any part of the site (even the rarer ones) it plays really well with the other WP Cache Plugins.</p>
]]></content:encoded>
			<wfw:commentRss>http://serialized.net/2009/10/great-wordpress-plugin-wp-widget-cache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Standard Deviation with Arduino</title>
		<link>http://serialized.net/2009/10/standard-deviation-with-arduino/</link>
		<comments>http://serialized.net/2009/10/standard-deviation-with-arduino/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 18:30:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[arduino]]></category>

		<guid isPermaLink="false">http://serialized.net/?p=320</guid>
		<description><![CDATA[My brother and I were playing around with Arduinos as part of my epic road trip this summer. He was trying to get a stable temperature reading from a sensor.
The issue was that the sensor was fine, except when it was rapidly transitioning from one temperature to another. For example, if the ambient temperature was [...]]]></description>
			<content:encoded><![CDATA[<p>My brother and I were playing around with Arduinos as part of my epic road trip this summer. He was trying to get a stable temperature reading from a sensor.</p>
<p>The issue was that the sensor was fine, except when it was rapidly transitioning from one temperature to another. For example, if the ambient temperature was 74, and suddenly a can of soda fresh from the fridge was placed on it, you&#8217;d get several &#8220;transitional readings&#8221; (70, 68, 52, 48, &#8230;) until the temperature finally stabilized.</p>
<p><img src="http://serialized.net/wp-content/uploads/2009/10/119421176_e1c82c8298-300x199.jpg" alt="Delicious Arduino" title="Delicious Arduino" width="300" height="199" class="alignright size-medium wp-image-326" /></p>
<p>We talked about various ways of detecting this case, but the most straightforward one seemed to be <a href="http://en.wikipedia.org/wiki/Standard_Deviation">Standard Deviation</a>, which Wikipedia explains much more clearly than I could.</p>
<p>I googled around for sample code or a library and didn&#8217;t find any. So even if my Google-fu is weak and there are great resources out there, now there&#8217;s another one.</p>
<p>The basic idea is that we take 10 samples quickly (20 ms apart), figure out the Standard Deviation, and if that&#8217;s close enough to zero, we can call this a &#8220;stable temperature.&#8221;</p>
<p>The <a href="http://hub.serialized.net/gitweb/?p=arduino.git;a=blob_plain;f=Standard_Deviation/Standard_Deviation.pde;hb=HEAD">full code</a> is available from <a href="http://hub.serialized.net/gitweb/">my git repository</a>, but here&#8217;s the core of it:</p>
<pre class="brush: cpp;">
  // Gather sample data

  float sampleSum = 0;
  for(int i = 0; i &lt; SAMPLES; i++) {
    s_val[i] = analogRead(TS);
    sampleSum += s_val[i];
    delay(20); // set this to whatever you want
  }
  float meanSample = sampleSum/float(SAMPLES);

  // HOW TO FIND STANDARD DEVIATION
  // STEP 1, FIND THE MEAN. (We Just did.)

  // STEP 2, sum the squares of the differences from the mean

  float sqDevSum = 0.0;

  for(int i = 0; i &lt; SAMPLES; i++) {
    // pow(x, 2) is x squared.
    sqDevSum += pow((meanSample - float(s_val[i])), 2);
  }

  // STEP 3, FIND THE MEAN OF THAT
  // STEP 4, TAKE THE SQUARE ROOT OF THAT

  float stDev = sqrt(sqDevSum/float(SAMPLES));

  // TADA, STANDARD DEVIATION.
  // this is in units of sensor ticks (0-1023)
</pre>
<p>So, hopefully the comments are self-explanatory (when combined with Wikipedia, if you&#8217;ve never seen Standard Deviation before.)</p>
<p>At the end of this block you have 2 useful variables defined: &#8216;meanSample&#8217;, which is the mean (average) value of all the samples you polled, and &#8217;stDev&#8217; &#8212; the standard deviation amongst all the samples.</p>
<p>This allows you to do things like</p>
<pre class="brush: cpp;">
if(stDev &lt; TOLERANCE) {
    // reading is stable enough
    fireMissleAt(meanSample);
}
</pre>
<p>An important note about the units &#8212; the Arduino analogRead values are 12 bit, meaning they range from 0-1023.<br />
In general, those numbers will &#8220;mean something&#8221; to you. Perhaps you can convert them to a temperature as we were doing, or a direction froma  compass, or a position on a pot. I chose to do the math with the numbers in as raw a form as possible. This means that if you have a sensorToTemp() function, you can call that on meanSample, but you&#8217;d also want to call that on stDev as well. Make sure to<br />
convert both values into meaningful values for your application. If you just want to know if the measurement is stable, then perhaps just knowing that the (12 bit) version of stDev is over your comfort level is enough.</p>
<p>Along with Standard Deviation came the need to print out some floating point numbers, so I also included some sample code to do that.<br />
It&#8217;s hard coded to send things to the serial port, but could be easily tweaked to fabricate a return string or print somewhere else.</p>
<pre class="brush: cpp;">
// This is a utility function for printing out floating point values
// Fixed at %0.2f form. (XX.YY, 2 digits after whatever decimal part there is.)
void printFloat(float var) {

  int int_part = int(var);
  int float_part = 100*var - (100*int_part);

  Serial.print(int_part, DEC);
  Serial.print(&quot;.&quot;);
  if(float_part &lt; 10) {
    Serial.print(&quot;0&quot;);
  }
  Serial.print(float_part, DEC);
}
</pre>
<p>Hopefully this helps someone else out. It was fun to write and I&#8217;m sure I&#8217;ll have a use for it someday!</p>
<p>Photo Credit (no that&#8217;s not me!)
<div xmlns:cc="http://creativecommons.org/ns#" about="http://www.flickr.com/photos/jeanbaptisteparis/119421176/"><a rel="cc:attributionURL" href="http://www.flickr.com/photos/jeanbaptisteparis/">http://www.flickr.com/photos/jeanbaptisteparis/</a> / <a rel="license" href="http://creativecommons.org/licenses/by-sa/2.0/">CC BY-SA 2.0</a></div>
]]></content:encoded>
			<wfw:commentRss>http://serialized.net/2009/10/standard-deviation-with-arduino/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>local::lib: Better perl when you don&#8217;t have root.</title>
		<link>http://serialized.net/2009/10/locallib-better-perl-when-you-dont-have-root/</link>
		<comments>http://serialized.net/2009/10/locallib-better-perl-when-you-dont-have-root/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 16:54:25 +0000</pubDate>
		<dc:creator>Joshua Barratt</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://serialized.net/?p=313</guid>
		<description><![CDATA[These days as we move increasingly to &#8216;the clouds&#8217;, it&#8217;s becoming common to get a server where you&#8217;ve got local root. However, those (from a provider and a user perspective) aren&#8217;t always the best way to go. Those are more expensive to provide (dedicated IP&#8217;s, more dedicated resources on the server) and thus more expensive [...]]]></description>
			<content:encoded><![CDATA[<p>These days as we move increasingly to &#8216;the clouds&#8217;, it&#8217;s becoming common to get a server where you&#8217;ve got local root. However, those (from a provider and a user perspective) aren&#8217;t always the best way to go. Those are more expensive to provide (dedicated IP&#8217;s, more dedicated resources on the server) and thus more expensive to buy. Also, in some use cases they might not scale so well if you&#8217;re buying a lower end one &#8212; if you buy 256MB of RAM, it&#8217;s pretty easy to push that into the red. On the administration side, the bar is raised for what you need to be able to do to solve simple problems. Adding an email account, or setting up the web server &#8212; all of these are solvable, and control panels can help, but what if you just want to serve some content? Why deal with it?</p>
<p>So, we still have shared hosting, in it&#8217;s various forms. I like the <a href="http://mediatemple.net">(mt) Grid Server</a>, but I will admit to being biased (a lot.)</p>
<p>So with shared hosting, you don&#8217;t have root. And managing software you need (to get useful web applications up and running) can be a pain &#8212; a lot of the documentation is biased towards the idea that you have a full server, be it virtual or physical.</p>
<p>If you don&#8217;t have root on your server, and you&#8217;re using perl (for any of the amazing Modern Perl tools and stacks out there,) I recommend checking out the awesome <a href="http://search.cpan.org/perldoc?local::lib">local::lib</a>.</p>
<p>Once you follow their &#8216;bootstrapping config&#8217; and set up your bashrc, it makes things feel like you&#8217;re on your own server. Just &#8216;cpan -i WordPress::Post&#8217; or &#8216;./Build install&#8217;, and it just works!</p>
<p>So a full install using local::lib would look like:<br />
Download and unpack local::lib:<br />
(Warning, update the link to the latest version, this is the current release:)</p>
<pre class="brush: plain;">
mkdir tmp
 cd tmp
wget http://search.cpan.org/CPAN/authors/id/A/AP/APEIRON/local-lib-1.004008.tar.gz
tar -zxvf local-lib-1.004008.tar.gz
</pre>
<p>cd into the local::lib directory, and then run:</p>
<pre class="brush: plain;">
perl Makefile.PL --bootstrap
make test &amp;&amp; make install
echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' &gt;&gt;~/.bash_profile
. ~/.bash_profile
</pre>
<p>And you&#8217;re done! Every time you ssh in, your environment will be set up to use your whole local tree. So even if you want perl&#8217;s New Fancy Hotness, all it takes is:</p>
<pre class="brush: plain;">
cpan -i Moose
</pre>
<p>One caveat if you&#8217;re using local::lib and trying to run this tool from cron, is that you&#8217;ll probably want to use a wrapper script to correctly set up the environment. (Sometimes you&#8217;ll need to set up the environment for your web apps, too &#8212; that can be done via .htaccess.)</p>
<p>Here&#8217;s an example wrapper script, set up to work on my MediaTemple (gs) account and work with my local::lib setup:</p>
<pre class="brush: plain;">
#!/bin/bash

#set up environment
HOME=/home/12345/users/.home
eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)

# run the script
$HOME/perl5/bin/mycron.pl
</pre>
<p>To make things work with your webapp, you need some &#8216;SetEnv&#8217; commands in the .htaccess. You can do this by just loading the local::lib module and checking the output:</p>
<pre class="brush: plain;">
%&gt; perl -I$HOME/perl5/lib/perl5 -Mlocal::lib
export MODULEBUILDRC=&quot;/home/12345/users/.home/perl5/.modulebuildrc&quot;
export PERL_MM_OPT=&quot;INSTALL_BASE=/home/12345/users/.home/perl5&quot;
export PERL5LIB=&quot;/home/68601/users/.home/perl5/lib/perl5:/home/12345/users/.home/perl5/lib/perl5/i386-linux-thread-multi:$PERL5LIB&quot;
export PATH=&quot;/home/12345/users/.home/perl5/bin:$PATH&quot;
</pre>
<p>Each one of those EXPORT statements needs to become a SetEnv statement.</p>
<pre class="brush: plain;">
# so this:
#export MODULEBUILDRC=&quot;/home/12345/users/.home/perl5/.modulebuildrc&quot;
# becomes:
SetEnv MODULEBUILDRC &quot;/home/12345/users/.home/perl5/.modulebuildrc&quot;
</pre>
<p>Repeat that for each one of the variable &#8216;export&#8217; lines, and you should be good to go! Affordable, scalable, low management overhead shared hosting and an easy way to get modern perl. </p>
]]></content:encoded>
			<wfw:commentRss>http://serialized.net/2009/10/locallib-better-perl-when-you-dont-have-root/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Questioning Coffee Geeks with Science</title>
		<link>http://serialized.net/2009/10/questioning-coffee-geeks-with-science/</link>
		<comments>http://serialized.net/2009/10/questioning-coffee-geeks-with-science/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 15:37:01 +0000</pubDate>
		<dc:creator>Joshua Barratt</dc:creator>
				<category><![CDATA[Food]]></category>

		<guid isPermaLink="false">http://serialized.net/?p=307</guid>
		<description><![CDATA[There are a few people I work with who are very passionate about coffee, which is something I enjoy very much as well, and have been known to geek out on.
Recently, I passed around this video from Sweet Maria&#8217;s, which is one of the bean providers the most enthusiastic of said co-workers shops with.
The Sweet [...]]]></description>
			<content:encoded><![CDATA[<p>There are a few people I work with who are very passionate about coffee, which is something I enjoy very much as well, and have been known to geek out on.</p>
<p>Recently, I passed around this <a href="http://picasaweb.google.com/lh/photo/ud1WWrBF2BOHnAl8FvvSyQ?feat=embedwebsite">video from Sweet Maria&#8217;s</a>, which is one of the bean providers the most enthusiastic of said co-workers shops with.</p>
<p>The Sweet Maria&#8217;s gent claimed as an aside in that video (which really raises the bar on coffee geekery, truly impressive) that one should always weigh one&#8217;s water, as the volume changes when it is heated.</p>
<p>I get that the volume changes, but it seemed to me that it can&#8217;t change <b>that</b> much. I realized this weekend that I had a way to find out exactly how: <a href="http://www.wolframalpha.com/">WolframAlpha</a>. I just had to ask it <a href="http://www.wolframalpha.com/input/?i=volume+of+1kg+of+water+at+90+degrees+celsius">Volume of 1kg of water at 90 degrees Celsius</a> and, lo and behold, it knows!</p>
<p>Curious, I punched in a few more numbers, and made the following chart: </p>
<div style="text-align:center;"><img src="http://serialized.net/wp-content/uploads/2009/10/Water-Volume-vs-Temp.png" alt="Water Volume vs Temp.png" border="0" width="600" height="458" /></div>
<p>So the water expands a pretty impressive 3.5% on it&#8217;s way from &#8220;very cold&#8221; to &#8220;coffee temp&#8221;. Assuming you start with water which is not totally chilled, however, the expansion starts to become less of an issue.</p>
<p>So, does it matter to most of us &#8212; no. We probably don&#8217;t measure our water within 3.5% accuracy on the best of days, anyway. (And if you have a hot water machine, like we do, which happens to dispense perfect temp water anyway, you&#8217;re measuring pre-expanded.)</p>
<p>But if you&#8217;re making any kind of serious volume, 3.5% might actually start to have an impact. It&#8217;s at least a sip out of a cup.</p>
<p>I&#8217;d say we have to call this geek &#8220;Plausible.&#8221; But I&#8217;m still not weighing my water.</p>
<p>Aside: if anyone knows how to use WolframAlpha to actually make a chart like this, let me know. It seems like it should be doable, I just couldn&#8217;t finesse my query in such a way to make it happen. <a href="http://www.omnigroup.com/applications/omnigraphsketcher/">OmniGraphSketcher to the rescue.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://serialized.net/2009/10/questioning-coffee-geeks-with-science/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FlickrPress now available: Turns Flickr RSS to Wordpress Posts</title>
		<link>http://serialized.net/2009/10/flickrpress-now-available-turns-flickr-rss-to-wordpress-posts/</link>
		<comments>http://serialized.net/2009/10/flickrpress-now-available-turns-flickr-rss-to-wordpress-posts/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 18:05:53 +0000</pubDate>
		<dc:creator>Joshua Barratt</dc:creator>
				<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://serialized.net/?p=304</guid>
		<description><![CDATA[My wife and I like to post a lot of photos of our son to his blog.

After using WordPress from both the browser and the iPhone client, I just wasn&#8217;t that happy using it for our pictures. On the other hand, we both love (and already use, and have Pro accounts on) Flickr.
Having the photos [...]]]></description>
			<content:encoded><![CDATA[<p>My wife and I like to post a lot of photos of our son to <a href="http://carterbarratt.com">his blog</a>.</p>
<div style="text-align:center;"><img src="http://serialized.net/wp-content/uploads/2009/10/carterbarratt_dontlikethiseither.jpg" alt="Carter's Site" border="0" width="422" height="368" /></div>
<p>After using WordPress from both the browser and the iPhone client, I just wasn&#8217;t that happy using it for our pictures. On the other hand, we both love (and already use, and have Pro accounts on) Flickr.</p>
<p>Having the photos &#8220;live&#8221; on Flickr means some handy things.</p>
<ol>
<li>They let you get an RSS feed of a tag. (We use &#8216;carterbarratt.&#8217;) This means we don&#8217;t even have to use an API key, which is convenient.</li>
<li>They always have an image available that&#8217;s sized to 500 on the longest side. This turns out to be a perfect image size (either height or width) for a lot of WordPress themes.</li>
<li>They handle video and make the thumbnails look exactly like a &#8220;non-video image&#8221; in the RSS feed.</li>
<li>Lots of things can upload to Flickr &#8212; we use mostly the desktop uploader (after exporting from Lightroom) and the new Flickr native client on our iPhones.</li>
<li>The exact same stuff (title, description) that I&#8217;d want on a photo blog is available when I upload to Flickr.</li>
</ol>
<p>So, FlickrPress was born. It&#8217;s a fairly simple perl script, intended to be run as a cron job, which uses <a href="http://search.cpan.org/perldoc?WordPress::Post">WordPress::Post</a> to create new blog posts for every flickr photo it finds with a certain tag, from certain users.</p>
<div style="text-align:center;"><img src="http://serialized.net/wp-content/uploads/2009/10/FlickrPress-flow.png" alt="FlickrPress Workflow" border="0" width="579" height="317" /></div>
<p>Check out the <a href="http://serialized.net/FlickrPress">FlickrPress page</a> for downloads and installation instructions.</p>
]]></content:encoded>
			<wfw:commentRss>http://serialized.net/2009/10/flickrpress-now-available-turns-flickr-rss-to-wordpress-posts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing perl system interactions</title>
		<link>http://serialized.net/2009/10/testing-perl-system-interactions/</link>
		<comments>http://serialized.net/2009/10/testing-perl-system-interactions/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 16:07:53 +0000</pubDate>
		<dc:creator>Joshua Barratt</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://serialized.net/?p=289</guid>
		<description><![CDATA[A lot of the code I end up needing to work on makes calls to various executables to read and process system state. It might be DTrace, or one of the tools that comes with the Virtuozzo/OpenVZ management suite, or one of the HP hardware monitoring tools &#8212; they all want to be called from [...]]]></description>
			<content:encoded><![CDATA[<p>A lot of the code I end up needing to work on makes calls to various executables to read and process system state. It might be DTrace, or one of the tools that comes with the Virtuozzo/OpenVZ management suite, or one of the HP hardware monitoring tools &#8212; they all want to be called from the command line.</p>
<p>In the old days, I probably would have just used perl backticks to run the command and capture the output. I&#8217;d &#8220;test&#8221; on a machine that had those tools installed, and call it a day.</p>
<pre class="brush: perl;">
my $output = `some system command`;
# process the output here
</pre>
<p>However, that&#8217;s pretty evil, and it&#8217;s essentially untestable.</p>
<p>Here&#8217;s a pattern that works pretty well.</p>
<p>The IPC::Run module includes a &#8216;run&#8217; command, which in the simple form takes 4 references: To a list of a command and it&#8217;s arguments, and then scalar references for the contents of Standard In, Standard Out, and Standard Error.</p>
<p>If all you care about is capturing STDOUT, you might call it like:</p>
<pre class="brush: perl;">
my @raidstate = (&quot;hpacucli&quot;, &quot;'controller slot=0 physicaldrive all show'&quot;)
my $raid_output;
IPC::Run::run(\@raidstate, \undef, \$raid_output, \undef);
</pre>
<p>Ok, but how does that help us test?<br />
Enter the venerable Test::MockModule.</p>
<p>All I need to do is override the run() function for the module in my test!</p>
<pre class="brush: perl;">
use Test::MockModule;

my $module = new Test::MockModule('IPC::Run');
$module-&gt;mock('run', \&amp;mock_ipc_run);
</pre>
<p>Ok, so how do I get the right content to get in the $raid_output?</p>
<p>It depends on how exactly you&#8217;re calling run: I hand-tuned this for the specific use case I&#8217;m doing right now, where I just care about capturing output.</p>
<p>What we do is store a list of command lines in the data block, followed by their output. When someone calls &#8216;run()&#8217; with one of those command lines, we send that output back to them.</p>
<pre class="brush: perl;">
sub mock_ipc_run {
    my($cmd, $stdin, $stdout, $stderr) = @_;
    # very important to rewind DATA so this subroutine can be called more than once
    seek(DATA, 0, 0);
    my $cmd_str = join(&quot; &quot;, @$cmd);
    while(&lt;DATA&gt;) {
        # iterate until we match the command name with '*' @ the beginning
        if(/^\* $cmd_str/) {
            while(&lt;DATA&gt;) {
                # until we find another command entry...
                if(/\*\s/) {
                    return;
                } else {
                    # pack the results into the $stdout reference we were given
                    $$stdout .= $_;
                }
            }
        }
    }
}
</pre>
<p>And the matching section in the DATA block:</p>
<pre class="brush: plain;">
__END__
* hpacucli 'controller slot=0 physicaldrive all show'

Smart Array P400i in Slot 0

  array A
   physicaldrive 1I:1:1 (port 1I:box 1:bay 1, SAS, 73.4 GB, OK)
   physicaldrive 1I:1:2 (port 1I:box 1:bay 2, SAS, 73.4 GB, OK)
   physicaldrive 1I:1:3 (port 1I:box 1:bay 3, SAS, 73.4 GB, OK)
   physicaldrive 1I:1:4 (port 1I:box 1:bay 4, SAS, 73.4 GB, OK)
   physicaldrive 2I:1:5 (port 2I:box 1:bay 5, SAS, 73.4 GB, OK)
   physicaldrive 2I:1:6 (port 2I:box 1:bay 6, SAS, 73.4 GB, OK)
</pre>
<p>And you&#8217;re done! This is nice and easily extensible. If you have several specific use cases (like output that actually starts with &#8216;* &#8216;, for example, or needing STDIN/STDERR) you&#8217;d need to modify it. It&#8217;s a handy general pattern for making &#8220;sysadmin code&#8221; a lot more like &#8220;developer code&#8221;, though. (The great thing is I was able to write and test this whole code suite on a VM that didn&#8217;t even have an HP raid controller, let alone hpacucli installed, for example.)</p>
]]></content:encoded>
			<wfw:commentRss>http://serialized.net/2009/10/testing-perl-system-interactions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Help me suffer for charity!</title>
		<link>http://serialized.net/2009/09/help-me-suffer-for-charity/</link>
		<comments>http://serialized.net/2009/09/help-me-suffer-for-charity/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 15:40:41 +0000</pubDate>
		<dc:creator>Joshua Barratt</dc:creator>
				<category><![CDATA[Ramble]]></category>

		<guid isPermaLink="false">http://serialized.net/?p=284</guid>
		<description><![CDATA[I&#8217;m raising money for the Wounded Warrior Project and Athletes For A Cure (Prostate Cancer Research) by participating in something called Fight Gone Bad.
The short version is this:

You donate
I go and REALLY REALLY bust my butt
I vomit (optional)
We help out some deserving people and (for those of us with prostates) maybe even ourselves.

&#8220;But Josh, how [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m raising money for the <a href="http://woundedwarriorproject.org/">Wounded Warrior Project</a> and <a href="http://afacblog.org/">Athletes For A Cure</a> (Prostate Cancer Research) by participating in something called <a href="http://www.fgb4.org/">Fight Gone Bad</a>.</p>
<p>The short version is this:</p>
<ol>
<li>You donate</li>
<li>I go and REALLY REALLY bust my butt</li>
<li>I vomit (optional)</li>
<li>We help out some deserving people and (for those of us with prostates) maybe even ourselves.</li>
</ol>
<p>&#8220;But Josh, how do I do this?&#8221; You ask.<br />
Good question! Just go to my easy-to-remember donation page:<br />
<a href="http://j.mp/WatchJoshSweat">http://j.mp/WatchJoshSweat</a><br />
In 30 seconds you can enter the amount you&#8217;d like to donate and a credit card number. Very easy!</p>
<p><b>Update:</b><b> Some people were curious about what the workout itself is.<br />
Straight from the Crossfit FAQ:</p>
<blockquote><p>
In this workout you move from each of five stations after a minute. This is a five-minute round from which a one-minute break is allowed before repeating. The workout is a total of 3 rounds.</p>
<p>The stations are:<br />
 1. Wall-ball: 20 pound ball, 10 ft target. (Reps)<br />
 2. Sumo deadlift high-pull: 75 pounds (Reps)<br />
 3. Box Jump: 20&#8243; box (Reps)<br />
 4. Push-press: 75 pounds (Reps)<br />
 5. Row: calories (Calories)<br />
The clock does not reset or stop between exercises. On call of &#8220;rotate,&#8221; the athlete/s must move to next station immediately for good score. One point is given for each rep, except on the rower where each calorie is one point.
</p></blockquote>
<p></b></p>
]]></content:encoded>
			<wfw:commentRss>http://serialized.net/2009/09/help-me-suffer-for-charity/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
