<?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>Software @ UNH</title>
	<atom:link href="http://software.unh.edu/feed/" rel="self" type="application/rss+xml" />
	<link>http://software.unh.edu</link>
	<description>by the U, for the U</description>
	<lastBuildDate>Tue, 16 Apr 2013 17:41:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>jQuery is(), not(), and ! is()</title>
		<link>http://software.unh.edu/2013/04/16/jquery-is-not-and-is/</link>
		<comments>http://software.unh.edu/2013/04/16/jquery-is-not-and-is/#comments</comments>
		<pubDate>Tue, 16 Apr 2013 14:58:39 +0000</pubDate>
		<dc:creator>Marcus Del Greco</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://software.unh.edu/?p=1411</guid>
		<description><![CDATA[jQuery lovers: this little distinction got me this morning, even though I should know it already. I&#8217;d explain it here, but the linked article does a fine job. Addendum: is it still worth using a JS abstraction library like jQuery? Yes.]]></description>
			<content:encoded><![CDATA[<p>jQuery lovers: <a href="http://ajpiano.com/the-opposite-of-jquerys-is-method-is-not-not-it-is-is/" target="_blank">this little distinction</a> got me this morning, even though I should know it already.  I&#8217;d explain it here, but the  linked article does a fine job.</p>
<p>Addendum: is it still worth using a JS abstraction library like jQuery?  <a href="https://medium.com/the-javascript-collection/ce3645cca083" target="_blank">Yes</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://software.unh.edu/2013/04/16/jquery-is-not-and-is/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Help!  I&#8217;m on OS X and My Mouse Won&#8217;t Work!</title>
		<link>http://software.unh.edu/2013/03/20/help-im-on-os-x-and-my-mouse-wont-work/</link>
		<comments>http://software.unh.edu/2013/03/20/help-im-on-os-x-and-my-mouse-wont-work/#comments</comments>
		<pubDate>Wed, 20 Mar 2013 23:47:56 +0000</pubDate>
		<dc:creator>Marcus Del Greco</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[IO]]></category>
		<category><![CDATA[mouse]]></category>
		<category><![CDATA[OS X]]></category>

		<guid isPermaLink="false">http://software.unh.edu/?p=1403</guid>
		<description><![CDATA[I am writing this post in hopes that the next poor Google searcher&#8230; if they can search at all&#8230; finds the solution quicker than I did. Sure, it only took me about a half hour, but that&#8217;s a lifetime these days. So my mouse stops working on the MacBook Pro. Oh, I can move it [...]]]></description>
			<content:encoded><![CDATA[<p>I am writing this post in hopes that the next poor Google searcher&#8230; if they can search at all&#8230; finds the solution quicker than I did.  Sure, it only took me about a half hour, but that&#8217;s a lifetime these days.</p>
<p>So my mouse stops working on the MacBook Pro.  Oh, I can move it around alright.  I can move it around all day and night.  I just can&#8217;t frakking <em>click</em>.  The left-click won&#8217;t work but the right-click (I have a two button Bluetooth mouse) will.  It&#8217;s amazing how quickly one realizes that Right Click isn&#8217;t fit to iron Left Click&#8217;s pants in the morning, when Left Click isn&#8217;t working.</p>
<p>OK.  This is just something wrong with that Bluetooth mouse, right?  So I try the trackpad.  Same behavior&#8230; I can move that cursor around wherever I like, but clicking is futile.  If you think this won&#8217;t make a grown man cry, you weren&#8217;t in my basement tonight.</p>
<p>Luckily, my keyboard still worked.  So with a little ALT-TAB I could get into my browser, tab around to the location field (thanks Chrome!) and do a Google search on this shiz.</p>
<p>Lots of talk about Bluetooth devices&#8230; Bluetooth devices in the next room, Bluetooth devices in the work bag, Bluetooth devices leaning up against stuff with their buttons getting pushed.</p>
<p>Makes sense.  So I turn off the power on my Bluetooth mouse.  No difference.  I yank the USB piece that talks to Bluetooth mouse.  No difference&#8230; trackpad still produces barren clicks.  So I yank every peripheral I have connected&#8230;. firewire hard drives, USB hub, audio system, second display.  NO DIFFERENCE.  A ZOMBIE IS LIVING IN MY MAC AND FEEDING ON ITS LEFT CLICK LIKE BRAINS.</p>
<p>The solution I finally arrived at after more searching, thank you keyboard I love you, was to disable Bluetooth entirely at the command line.  This is the same thing as unchecking &#8216;On&#8217; in System Preferences -> Bluetooth, but trying doing THAT with Left Click pacing the picket line.</p>
<p>COMMAND-SPACE got me into Spotlight, where I typed &#8220;Terminal&#8221;, arrowed down and hit ENTER.  Now at the command line, I typed:</p>
<blockquote><p>sudo defaults write /Library/Preferences/com.apple.Bluetooth &#8220;ControllerPowerState&#8221; -bool FALSE</p></blockquote>
<p>That turned Bluetooth OFF&#8230; sort of.  That turns the preference off, but to kill any existing Bluetooth connections dead, a little more magic is required:</p>
<blockquote><p>sudo killall -SIGHUP blued</p></blockquote>
<p>And with that: my trackpad was restored to normal.  I&#8217;m pretty happy with my trackpad at this very moment, but I&#8217;m sure I&#8217;ll start using Bluetooth devices again&#8230; with the above experience in the back of my mind.</p>
]]></content:encoded>
			<wfw:commentRss>http://software.unh.edu/2013/03/20/help-im-on-os-x-and-my-mouse-wont-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Q: How Many Developers Does It Take To Screw In A Light Bulb?</title>
		<link>http://software.unh.edu/2013/03/11/q-how-many-developers-does-it-take-to-screw-in-a-lightbulb/</link>
		<comments>http://software.unh.edu/2013/03/11/q-how-many-developers-does-it-take-to-screw-in-a-lightbulb/#comments</comments>
		<pubDate>Mon, 11 Mar 2013 23:26:20 +0000</pubDate>
		<dc:creator>Marcus Del Greco</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[light]]></category>
		<category><![CDATA[SDK]]></category>

		<guid isPermaLink="false">http://software.unh.edu/?p=1391</guid>
		<description><![CDATA[A: However many are needed to program the new Philips iOS SDK for light bulbs&#8230;]]></description>
			<content:encoded><![CDATA[<p>A: However many are needed to program the new <a href="http://www.tuaw.com/2013/03/11/phillips-debuts-ios-sdk-for-its-light-bulbs/" target="_blank">Philips iOS SDK</a> for light bulbs&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://software.unh.edu/2013/03/11/q-how-many-developers-does-it-take-to-screw-in-a-lightbulb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit Testing is a Little Bit Like Flossing</title>
		<link>http://software.unh.edu/2013/01/31/unit-testing-is-a-little-bit-like-flossing/</link>
		<comments>http://software.unh.edu/2013/01/31/unit-testing-is-a-little-bit-like-flossing/#comments</comments>
		<pubDate>Thu, 31 Jan 2013 21:53:40 +0000</pubDate>
		<dc:creator>Bill Costa</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[application development]]></category>
		<category><![CDATA[coding standards]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://software.unh.edu/?p=1317</guid>
		<description><![CDATA[You know you should floss, but you don&#8217;t have time to do it right now.  Sure, you floss when you have an annoyance, like that piece of pulled pork caught between your molars.  And you floss for a couple of days, after your dental hygienist has given you &#8216;the lecture&#8217;.  But in the end, you [...]]]></description>
			<content:encoded><![CDATA[<p>You know you should floss, but you don&#8217;t have time to do it right now.  Sure, you floss when you have an annoyance, like that piece of pulled pork caught between your molars.  And you floss for a couple of days, after your dental hygienist has given you &#8216;the lecture&#8217;.  But in the end, you don&#8217;t have time to do it right now.  Maybe later.</p>
<p>Writing unit tests is a little bit like flossing.  You know it&#8217;s a good thing to do.  It may not feel like fun while you&#8217;re doing it, but you&#8217;re almost always glad you did it when you&#8217;re done.  Like flossing, if you&#8217;re going to do it, and do it consistently, you need to try and establish a habit.  And there&#8217;s no time like now to get started.</p>
<p>In the directory where you stash your modules, create a subdirectory named &#8220;<strong>t</strong>&#8220;.  Yes, you&#8217;ve seen this directory name before when installing a module from CPAN.  Don&#8217;t panic!  You&#8217;re not going to have to build a complete distribution.  You&#8217;re just creating a place to stash your tests that is both convenient and follows the conventions used by the Perl <a title="Documentation for the Perl prove utility." href="http://search.cpan.org/~ovid/Test-Harness-3.26/bin/prove" target="_blank">prove</a> utility.  Now, the next time you create some new function or method in one of your modules, create a unit test for that function in your &#8220;<strong>t</strong>&#8221; directory.  For example, let&#8217;s say I&#8217;m creating a new utility function call <strong>mySum()</strong> in the module <strong>MyModule</strong>.  I&#8217;ll also create a new unit test script named <strong>mySum.t</strong>.  As I write the function in the module, I&#8217;ll also start writing the unit tests in the test script.  Writing some logic to handle an edge case?  Write a test to probe that edge.  Test it.  Right now!  Now code up the next hard part, and test that.  Here&#8217;s a simple example you can use as a starting template:</p>
<pre class="brush: perl; title: ; notranslate">
#!/usr/bin/env perl
#
#       File: t/mySum.t
#      Usage: prove mySum.t
#   Abstract: Test my wonderful MyMod::mySum() service.

use warnings FATAL =&gt; qw(all);   # Make all warnings fatal.
use strict;                      # Keep things squeaky clean.
use Test::More;                  # Lots of testing goodies.
use File::Basename;              # Easy basic filespec parsing.
use lib '..';                    # Where to find our own modules.

my $ownName = basename($0); # For error reporting.

die(&quot;? $ownName: no command line args expected\n_ &quot;, join(' ', @ARGV), &quot;\n_&quot;)
 if (scalar(@ARGV) &gt; 0);

use_ok('MyMod') or exit(1); # The module we're testing.

is( MyMod::mySum(),                 0,         &quot;sum of nothing is zero&quot;       );
is( MyMod::mySum(undef(), undef()), 0,         &quot;sum of two nothings is zero&quot;  );
is( MyMod::mySum(1,2,3,'fred'),     undef(),   &quot;fred is not a number&quot;         );
is( MyMod::mySum(2,2),              4,         &quot;two small positive integers&quot;  );

my $x = 2;

is( MyMod::mySum($x,$x),            4,         &quot;two small positive integers&quot;  );
is( MyMod::mySum($x,\$x),           undef(),   &quot;can't sum a scalar reference&quot; );

# etc.

done_testing();

# EOF: mySum.t
</pre>
<p>The example above uses the <strong>is()</strong> test function which, along with <strong>ok(),</strong> covers a lot of the sort of simple test cases you&#8217;ll want to do.  But there are lots of other very useful test functions beyond these, so be sure to check out the <a title="Test::More module documentation." href="http://perldoc.perl.org/Test/More.html" target="_blank">Test::More</a> documentation for more details.</p>
<p>To run your test, from your module directory, you can do either:</p>
<p>$ t/mySum.t<br />
ok 1 &#8211; use MyMod;<br />
ok 2 &#8211; sum of nothing is zero<br />
ok 3 &#8211; sum of two nothings is zero<br />
ok 4 &#8211; fred is not a number<br />
ok 5 &#8211; two small positive integers<br />
ok 6 &#8211; two small positive integers<br />
ok 7 &#8211; can&#8217;t sum a scalar reference<br />
1..7<br />
$</p>
<p>&#8230;or&#8230;.</p>
<p>$ prove t/mySum.t<br />
t/mySum.t .. ok<br />
All tests successful.<br />
Files=1, Tests=7, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.02 cusr 0.00 CPU)<br />
Result: PASS<br />
$</p>
<p>As your test library grows, you can just enter the <strong>prove</strong> command with no parameters and it will automatically run <em>all</em> of the <strong>*.t</strong> files it finds in your test directory.</p>
<p>So, don&#8217;t worry about back-filling all of those unit tests you <em>should</em> have written.  But <em>do</em> start getting into the habit of creating unit tests, function by function, as you create new code, particularly for those utility functions that have very narrow, well defined jobs.  For your convenience, here is the toy module that was used with the above unit test.</p>
<pre class="brush: perl; title: ; notranslate">
package MyMod;

# Simple demo module with simple demo function.

use warnings FATAL =&gt; qw(all);
use strict;
use Scalar::Util qw(looks_like_number);

sub mySum

#  Precondition: Parameters consist of zero or more numeric values.
#
# Postcondition: The sum of all the numeric values is returned as our
#                functional value.  Undefined parameters are silently
#                ignored.  We return undefined if one or more values
#                do not appear to be numeric (i.e. a usage error).  We
#                return 0 if there are no defined parameters.
#
#     Unit Test: t/mySum.t

{
  my $sum = 0;
  foreach my $x (@_)
    {
      next if (not defined($x));
      return() if (not looks_like_number($x));
      $sum += $x;
    }

  return($sum);
}

1;  # So endith your typical Perl module.
</pre>
]]></content:encoded>
			<wfw:commentRss>http://software.unh.edu/2013/01/31/unit-testing-is-a-little-bit-like-flossing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programus Interruptus</title>
		<link>http://software.unh.edu/2013/01/24/programus-interruptus/</link>
		<comments>http://software.unh.edu/2013/01/24/programus-interruptus/#comments</comments>
		<pubDate>Thu, 24 Jan 2013 18:49:56 +0000</pubDate>
		<dc:creator>Bill Costa</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://software.unh.edu/?p=1308</guid>
		<description><![CDATA[This is why, when I have some particularly hard coding to do, I try and do it at home&#8230; &#8211; Why Programmers Work at Night &#8211; Programmer Interrupted Although now that my spouse is retired, it is getting more difficult to get long stretches of interrupted time at home.  I think there&#8217;s a potential market for [...]]]></description>
			<content:encoded><![CDATA[<p>This is why, when I have some particularly hard coding to do, I try and do it at home&#8230;</p>
<p>&#8211; <a title="Why Programmers Work at Night" href="http://swizec.com/blog/why-programmers-work-at-night/swizec/3198#ixzz2IcIlLyHD" target="_blank">Why Programmers Work at Night</a></p>
<p>&#8211; <a title="Programmer Interrupted" href="http://blog.ninlabs.com/2013/01/programmer-interrupted/" target="_blank">Programmer Interrupted</a></p>
<p>Although now that my spouse is retired, it is getting more difficult to get long stretches of interrupted time at home.  I think there&#8217;s a potential market for programmer isolation pods.  An <a href="http://en.wikipedia.org/wiki/Isolation_tank" target="_blank">isolation tank</a> could work, if you could solve the problem of needing a waterproof keyboard and mouse.</p>
]]></content:encoded>
			<wfw:commentRss>http://software.unh.edu/2013/01/24/programus-interruptus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Happy Birthday, Perl</title>
		<link>http://software.unh.edu/2012/12/18/happy-birthday-perl/</link>
		<comments>http://software.unh.edu/2012/12/18/happy-birthday-perl/#comments</comments>
		<pubDate>Tue, 18 Dec 2012 18:49:59 +0000</pubDate>
		<dc:creator>Marcus Del Greco</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://software.unh.edu/?p=1304</guid>
		<description><![CDATA[The Perl programming language turns 25 today. Little did I know when I was 12 years old that I would learn a language being birthed at that moment, and pursue a career in speaking it. Here is a tribute to / history of Perl&#8217;s first 25 years. Long live!]]></description>
			<content:encoded><![CDATA[<p>The Perl programming language turns 25 today.  Little did I know when I was 12 years old that I would learn a language being birthed at that moment, and pursue a career in speaking it.</p>
<p>Here is a <a href="http://news.perlfoundation.org/2012/12/the-first-twenty-five-years.html">tribute to / history of Perl&#8217;s first 25 years</a>.</p>
<p>Long live!</p>
]]></content:encoded>
			<wfw:commentRss>http://software.unh.edu/2012/12/18/happy-birthday-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>out of sorts</title>
		<link>http://software.unh.edu/2012/08/08/out-of-sorts/</link>
		<comments>http://software.unh.edu/2012/08/08/out-of-sorts/#comments</comments>
		<pubDate>Wed, 08 Aug 2012 20:10:38 +0000</pubDate>
		<dc:creator>Paul Sand</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://software.unh.edu/?p=1292</guid>
		<description><![CDATA[Not that it matters, but while reading through the sort(1) man page, I noticed a new (to me) option: -R, &#8211;random-sort sort by random hash of keys Yes, newer versions of sort will actually shuffle your input data.I&#8217;m not sure if that&#8217;s a cool thing for a command named sort to do, but I like [...]]]></description>
			<content:encoded><![CDATA[<p>Not that it matters, but while reading through the sort(1) man page, I noticed a new (to me) option:</p>
<p><strong>-R</strong>, <strong>&#8211;random-sort</strong><br />
sort by random hash of keys</p>
<p>Yes, newer versions of sort will actually <em>shuffle</em> your input data.I&#8217;m not sure if that&#8217;s a cool thing for a command named sort to do, but I like it anyway.</p>
<p>A quick test (on Red Hat 6) shows that it really is random: you don&#8217;t get the same shuffle each time.</p>
<p>Good replacement for the Perl one-liner:</p>
<p>perl -MList::Util -e &#8216;print List::Util::shuffle &lt;&gt;&#8217;</p>
<p>(Added later: many versions of Linux include the &#8220;shuf&#8221; command.)</p>
]]></content:encoded>
			<wfw:commentRss>http://software.unh.edu/2012/08/08/out-of-sorts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perl pet peeves: named parameters for methods</title>
		<link>http://software.unh.edu/2012/07/16/perl-pet-peeves-named-parameters-for-methods/</link>
		<comments>http://software.unh.edu/2012/07/16/perl-pet-peeves-named-parameters-for-methods/#comments</comments>
		<pubDate>Tue, 17 Jul 2012 01:49:54 +0000</pubDate>
		<dc:creator>Bill Costa</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://software.unh.edu/?p=1208</guid>
		<description><![CDATA[A colleague was creating an app that used the Net::LDAP module, a module I have been using myself for a very long time now. In the code there was the statement: &#8230;that was returning a &#8220;Bad filter&#8221; error. Turns out there was no problem with the filter text, but there was with the search statement&#8212;the [...]]]></description>
			<content:encoded><![CDATA[<p><P>A colleague was creating an app that used the Net::LDAP module, a module I have been using myself for a very long time now. In the code there was the statement:</p>
<pre class="brush: perl; title: ; notranslate">my $msg = $ldap-&gt;search(bind_dn =&gt; $base_dn, filter =&gt; $filter);</pre>
<p>&#8230;that was returning a &#8220;Bad filter&#8221; error. Turns out there was no problem with the filter text, but there was with the search statement&#8212;the parameter label <CODE>bind_dn</CODE> is not a valid keyword for this module.</P></p>
<p><P>I did something similar a long time ago, using a parameter label for the <CODE>bind()</CODE> method that actually belonged to <CODE>new()</CODE>. The parameter and value were accepted without comment. It didn&#8217;t cause an error, it was just silently ignored since it was totally unexpected.</P></p>
<p><P>As I&#8217;m sure you know, when passing named parameters to a method, what you are really passing is a hash. So:</p>
<pre class="brush: perl; title: ; notranslate">filter =&gt; $filter</pre>
<p>&#8230;is really a hash entry with &#8216;filter&#8217; as the key getting assigned the value from the scalar $filter. Now what you would like is for the method to throw an error if you misspell a key, but for the Net::LDAP module, and some other CPAN code I&#8217;ve seen, no check is done to see if an unexpected key is defined. The justification for this is the possible use of inheritance. If you pass a &#8220;foo&#8221; parameter to an object, <EM>it</EM> may not know what to do with &#8220;foo&#8221; but one of the other methods inherited by that object may. That&#8217;s why you&#8217;ll see things like&#8230;</p>
<pre class="brush: perl; title: ; notranslate">my($self, %opts) = @_;</pre>
<p>and then later&#8230;</p>
<pre class="brush: perl; title: ; notranslate">$self-&gt;someOtherMethod($this, $that, %opts);</pre>
<p>As for my own code, I&#8217;m still working on coming up with a good way to used named parameters with methods where all of the methods that get a set of named parameters have to &#8216;claim&#8217; the ones that that particular method is using, so that in the end, if there are any unclaimed named parameters, an exception is thrown. Haven&#8217;t come with what I think is a clean solution, but I&#8217;m still thinking about it.</p>
<p>I hope this is the sort of thing Moose fixes.</p>
]]></content:encoded>
			<wfw:commentRss>http://software.unh.edu/2012/07/16/perl-pet-peeves-named-parameters-for-methods/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Reports from OSCON 2012</title>
		<link>http://software.unh.edu/2012/07/16/reports-from-oscon-2012/</link>
		<comments>http://software.unh.edu/2012/07/16/reports-from-oscon-2012/#comments</comments>
		<pubDate>Mon, 16 Jul 2012 17:06:32 +0000</pubDate>
		<dc:creator>Marcus Del Greco</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[conferences]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[moose]]></category>

		<guid isPermaLink="false">http://software.unh.edu/?p=1197</guid>
		<description><![CDATA[Day 1 git It is Monday morning, and I am attending a(nother) tutorial on git (Get Better at Git). I am fully convinced that git is a better tool than Subversion at this point; I am also convinced it&#8217;s harder to fully understand and use. How these things can both be true speaks to the [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm9.staticflickr.com/8283/7619540454_2cabcbbd68_z.jpg"></p>
<p><strong>Day 1</strong></p>
<p><strong>git</strong></p>
<p>It is Monday morning, and I am attending a(nother) tutorial on git (<a href="http://www.oscon.com/oscon2012/public/schedule/detail/23907" target="_blank">Get Better at Git</a>). I am fully convinced that git is a better tool than Subversion at this point; I am also convinced it&#8217;s harder to fully understand and use. How these things can both be true speaks to the complexity of managing source code. It&#8217;s pretty clear that in a highly collaborative project, git is the way to go. That isn&#8217;t to say there aren&#8217;t thousands of projects using Subversion successfully, but, mastery of git would certainly reduce the pain in reaching the same success.</p>
<p>But mastery of git takes time. Fluency takes time. It occurs to me that the quickest path to fluency is immersion, and taking one or two classes on git does not immersion make. I do long, at times, to work in a hardcore dev shop to become fluent in git&#8230; just as I long, yet more often, to live in Quebec City or Paris and become fluent in French.</p>
<p><strong>Moose</strong></p>
<p>My Monday <a href="http://www.oscon.com/oscon2012/public/schedule/detail/23224" target="_blank">afternoon session is on Moose</a>, the most popular set of modules that extends Perl&#8217;s object support. As with git, I won&#8217;t write all my technical notes here&#8230; I&#8217;m just going to soak it in. Immerse myself as it were for the three hours I&#8217;ll have.</p>
<p>Okay I lied. I am already sort of liking Moose. When defining an object, you can label its attributes (think &#8216;values&#8217;) as &#8216;ro&#8217; (read-only) or &#8216;rw&#8217; (guess), make any of them required, and strongly type them. This is really fantastic. Honestly, I am often fairly lazy on the server side when it comes to validation, having already done the work on the client end in Javascript to try and assure the right values come in. But the client side is not completely in a developer&#8217;s controlling hands, so, it cannot be relied upon. Granted, Moose will crash your program if your constraints are violated, but I&#8217;d rather crash in such event than enter into an unexpected state.</p>
<p>I&#8217;m tempted to rejigger my Remedy and Pinnacle modules to use Moose, but I sort of hope I can get away with Moose::Lite. Performance won&#8217;t be much of an issue running atop FastCGI, but the dependency tree for Moose proper is massive, and I don&#8217;t want to acquire that much baggage quite yet.</p>
<p>But dang, Moose is neat. I love the concept of &#8216;advise&#8217;. This is a kind of flow control in object land. You can define what happens &#8216;before&#8217; or &#8216;after&#8217; a method is run, or even wrap a method with &#8216;around&#8217; if you need access to its internals. The best analogy I can make is probably applicable to object orientation in general&#8230; it&#8217;s like stuffing your money deeper in your pocket so it has less chance of falling out. Substitue &#8216;logic&#8217; for &#8216;money&#8217;.</p>
<p>When you have a class that inherits from more than one, it is called &#8216;diamond&#8217; or &#8216;multiple inheritance&#8217;. It&#8217;s dodgy and error prone. Moose solves this with the concept of &#8216;roles&#8217;. I&#8217;m trying to wrap my mind around this, but it seems as though a role is a kind of validation for the relationship between classes. Ah: it enables <em>horizontal</em> code reuse (roles and classes) rather than strictly vertical (classes and sub-classes). Apparently, using roles in Moose is far more common than subclassing at all.</p>
<p>Moose finally broke my mind this afternoon. Much of this I&#8217;d need to work with to begin to understand.</p>
<p><img src="http://farm9.staticflickr.com/8006/7619538896_3fc4952d93_z.jpg"></p>
<p><strong>Day 2</strong></p>
<p><strong>Modern Perl</strong></p>
<p>Tuesday morning and I am pleased to be attending <a href="http://www.oscon.com/oscon2012/public/schedule/detail/23275" target="_blank">New Features of the Modern Perls</a> by Damian Conway. Damian&#8217;s talks are worth the price of admission in themselves and everything else is gravy.</p>
<p>Something I did not know: when upgrading from 5.8, any XS modules you use need to be recompiled for any new version of Perl you move to. Damian is making a plea for Perl developers to upgrade, commenting that the Perl community will only be supporting the latest release and the previous two releases&#8230; meaning, security updates only for older versions of Perl. This means if you encounter an obscure, non-security related bug in an older version of Perl, it may not get fixed, and more importantly, module authors will be requiring more recent versions of Perl and the CPAN will move past you. He recommends targeting 5.14 at this time.</p>
<p>Interestingly, to preserve backward compatibility, you must enable new features explicitly in Perl versions starting with 5.10. This is to prevent new keywords from accidentally clashing with user subroutine names. But if you&#8217;re ready to move forward, you can enable all features in addition to requiring a minimum version of Perl simply with:</p>
<pre class="brush: perl; title: ; notranslate">use v5.14</pre>
<p>Now he&#8217;s making me want to upgrade just to use <strong>say</strong> (which is <strong>print</strong> with an implicit newline). Also, smartmatching (the new <strong>~~</strong> operator) is brilliant, a feature Damian invented for Perl. Another double-character operator added to recent Perls is <strong>//</strong>, the defined-or operator, which is better for setting default values (as below) than using <strong>||</strong>, because <strong>||</strong> tests for true/false, not defined-ness.</p>
<pre class="brush: perl; title: ; notranslate">my $number = $number // 42;</pre>
<p>The above case would assign $number a value of 0 if it had started off that way, whereas using <strong>||</strong> would have seen a 0 as false and assigned $number the 42.</p>
<p>Damian on Moose: &#8220;It annoys me just enough so that I don&#8217;t want to use it.&#8221; Now, he also has a lot to say in favor of Moose, but mostly complains of the startup time and isn&#8217;t crazy about the declaration syntax.</p>
<p>Another very cool feature in recent Perls is named captures out of regexes&#8230; numbered captures are too easy to get wrong. Think using named parameters to pass to subroutines instead of an order-dependent array. It&#8217;s just better.</p>
<p><strong>jQuery Mobile</strong></p>
<p>My Tuesday <a href="http://www.oscon.com/oscon2012/public/schedule/detail/23876" target="_blank">afternoon session is on jQuery Mobile</a>.  It&#8217;s safe to assume that I&#8217;ll be building some mobile apps in the coming decade, and this is one of my likely tools.  If I remain at the University during that time, jQuery Mobile is a *more* likely platform than native applications targeted to iOS, Android or some other emerging mobile OS.  That is, unless successful alum donate a native apps development budget.  But that wouldn&#8217;t be the best use of money, would it?</p>
<p>I&#8217;ve been following the jQuery projects (core, jQueryUI, and now jQuery Mobile) pretty closely for the past few years, and now load core and UI by default in my webstuff.  Bring mobile into the mix is the logical next step.  I already have an idea of the app I want to write&#8230; but have a ton of backend work to complete before I get proper access to the data I need.  I suppose that shouldn&#8217;t stop me from prototyping the front end&#8230; in my free time (stop laughing).</p>
<p><img src="http://farm9.staticflickr.com/8021/7619555970_412d9905d3_z.jpg"></p>
<p><strong>Day 3</strong></p>
<p>Day 3 begins the shorter sessions of the conference proper, following the keynotes.  They had the mayor this year, who proclaimed Portland an &#8216;open source city&#8217;, and who made some funny jokes.  There were some other semi-inspiring appearances amongst the keynotes, but as I decided to watch instead of type, I don&#8217;t have the time to relay these now. </p>
<p><a href="http://www.oscon.com/oscon2012/public/schedule/detail/23819" target="_blank">Perl 5 Today, Tomorrow and Christmas</a> is the first session I am attending this morning.  Ricardo Signes is the current Perl 5 project lead (Pumpking), so you might call him a reliable source on the subject.  He was also the guy who presented on Moose a couple days ago.</p>
<p>This is mostly a talk about the challenges in managing the Perl project, most of which (surprise!) are human in nature.  Apparently the p5p (Perl 5 Porters) mailing list is a great place to get into an argument but not always a great place for a Pumpking to spend his days.  There is a lot of talk at these conferences about &#8216;getting along&#8217; in open source communities.  Now he&#8217;s making an analogy I&#8217;ve often thought of, that of software coming about via &#8216;intelligent evolution&#8217;&#8230; a mix between intelligent design and evolution.</p>
<p>Next up, <a href="http://www.oscon.com/oscon2012/public/schedule/detail/24202" target="_blank">Programming In The Future</a>, a look at how the craft might evolve in the next 25 years through the lens of how Perl has evolved over the <em>past</em> 25.  This turned out to be a nit of a meandering talk, but included an interesting history of the most significant moments in Perl history, 1987 to present.  It&#8217;s hard to imagine you couldn&#8217;t write a Perl module until 1994.  Now he&#8217;s talking about parallel and functional programming, two somewhat advanced programming tasks that people seem to imagine becoming easier in the future, and some examples of how we do these things in Perl today.</p>
<p>Another yummy lunch, this one thanks to Google, and now I am in <a href="http://www.oscon.com/oscon2012/public/schedule/detail/23573" target="_blank">Test Driven UI Development</a>.  This is a very challenging endeavor.  This talk centers on a toolset from the Java/Groovy world, but which could be applied to other platforms.  I must say though: I cannot watch much of this test-driven development stuff without being secretly glad I don&#8217;t do it.  I just seems like another codebase to maintain, which itself would always be breaking, perhaps saving me an error here or there, but which would in general dilute my productivity.  It is interesting to see the speaker write the test <em>before</em> he writes the HTML for a simple form, though, complete with human readable comments&#8230; all very nice documentation.  The notion of &#8216;testable code&#8217; is about being able to select the elements in the DOM that you need to test, so, jQuery-like, you may be adding ids, but in this case, perhaps only to select them in the test suite.  Dear me.  The speaker discourages uses CSS classes as selectors in your test suite, because you may have front end developers mucking with class names.  He mentions testing AJAX can be tricky, which I would have guessed, but that you can access return methods with jQuery and similar in order to check success in many cases.</p>
<p>To finish off the day, I&#8217;m attending <a href="http://www.oscon.com/oscon2012/public/schedule/detail/23271" target="_blank">The Conway Channel</a>, another Damian Conway talk.  Entertaining as expected, and I immediately went to play with IO::Prompter and Lingua::EN::Inflect, two of the modules he has updated this year.  However IO::Prompter required Perl 5.10+, so&#8230; heck, why have I been putting off trying Perlbrew so I can run any version of Perl that I want?  Now building and compiling 5.14.2.  :)</p>
<p><img src="http://farm8.staticflickr.com/7125/7619551728_a1746674d1_z.jpg"></p>
<p><strong>Day 4</strong></p>
<p>Thursday morning and I had been planning to attend <a href="http://www.oscon.com/oscon2012/public/schedule/detail/24437" target="_blank">this EFF session</a>, but it was full.  So I walked around the Expo Hall, checked out the booths, grabbed some stickers and pens, that kind of stuff.</p>
<p>Next up is the long awaited <a href="http://www.oscon.com/oscon2012/public/schedule/detail/23270" target="_blank">Taming Perl Regexes</a>, another Damian Conway talk, in which he will is launching a tool called &#8216;rxrx&#8217; that he had hinted at in the video he sent to YAPC::NA.  It&#8217;s an incredible debugger for regular expressions, installable from CPAN as Regexp::Debugger.  I will try to post a short screen cap of this tool at work once I get it installed.</p>
<p>I&#8217;m starting my afternoon with <a href="http://www.oscon.com/oscon2012/public/schedule/detail/23994" target="_blank">Advanced MySQL Replication Architectures</a>, presented by some Oracle guys.  So far this is high-level view of different replication architectures; I was hoping for a little how-to with some commands.  Oh well, sometimes you hit a session that isn&#8217;t what you&#8217;re looking for.</p>
<p>Next up is <a href="http://www.oscon.com/oscon2012/public/schedule/detail/23885" target="_blank">Cooking Perl with Chef</a>, which I have high hopes for.  Having used Perlbrew for the first time today, I am feeling bold about tossing Perl itself around.  Here are the problems and their solutions as presented:</p>
<ul>
<li>application-specific Perl: Perlbrew</li>
<li>application-specific @INC Path: local::lib</li>
<li>versioned application code: git, SVN, etc.</li>
<li>versioned module dependencies: Carton</li>
<li>automate the previous four: Chef (scripted using Ruby)</li>
</ul>
<p>Chef usually requires a server of its own, but if you want to save on that overhead and only have a handful of nodes to deploy to, you can use Chef Solo.  Still, I think Chef would be the last piece I&#8217;d add to this puzzle, if at all, considering that I already have a scripted deployment routine that is beginning to pull all the same levers and push the same buttons.  But adding Perlbrew and Carton (which leverages local::lib) are musts.  Hopefully I&#8217;ll be deploying with those within a year.  We&#8217;ll see!</p>
<p>These last session I am attending today is <a href="http://www.oscon.com/oscon2012/public/schedule/detail/23264" target="_blank">What Every Web Developer Should Know About Database Optimization</a>.  This was largely review for me, but I did get a reminder that occasionally JOIN order could be important, and oddly enough, yet another warning about ORMs.  Object Relational  Mappers can be hell on your database, especially if you don&#8217;t give the proper cues, similar to how you&#8217;d optimize SQL, just not directly.  Explain to me why I want to use an ORM, again?  (I know, I know&#8230;)</p>
<p>At 7pm (PST of course) is Larry Wall&#8217;s State of the Onion address, the official update on Perl&#8217;s present and future, but I&#8217;m whupped.</p>
<p><img src="http://farm9.staticflickr.com/8283/7619560144_b9ebc6a2f0_z.jpg"></p>
<p><strong>Day 5</strong></p>
<p>I skipped the keynotes this morning in favor of a long breakfast.  This last day is a half day of sessions.</p>
<p>The first for me is another database session: <a href="http://www.oscon.com/oscon2012/public/schedule/detail/24445" target="_blank">Optimizing MySQL Configuration</a>.  Thus far we&#8217;re getting a list of optimizations not to try.  The <pre>mysqltuner</pre> utility sounds worth trying out.  Here&#8217;s an interesting recommendation: set skip_name_resolve to 1 and don&#8217;t use hostnames in GRANTs.  It makes sense that skipping name lookups would increase performance a tad, but, it also increases your administrative overhead in maintaining IP addresses in GRANTs, since IPs change more often than names.  Now we are going over the million and one configuration variables available to change in MySQL, many of which are MyISAM or InnoDB dependent (this had me detouring to a <a href="http://www.kavoir.com/2009/09/mysql-engines-innodb-vs-myisam-a-comparison-of-pros-and-cons.html" target="_blank">storage engine comparison</a> since I have been using MyISAM all this time).  </p>
<p>I don&#8217;t think I&#8217;d like to be the steward of a large database that was always needing tuning.  It seems so fiddly.</p>
<p>Next up, some attention to the front end of things after dwelling on the back end for while: <a href="http://www.oscon.com/oscon2012/public/schedule/detail/24064" target="_blank">Designing HTML5 Components</a>.  Okay, this was not what I expected at all.  He is using a Java framework called Vaadin (the Finnish word for &#8216;reindeer&#8217;) and the goal is apparently to create <em>reusable</em> web components.  This is really yet another web framework, this one from Java land, and by reusable he means, reusable in this particular framework&#8217;s ecosystem.  You write in Java, and it compiles some Javascript for each of your target browsers.  Pretty slick, but you&#8217;ve got to go &#8216;all in&#8217; to get the bennies.</p>
<p>The last session I am attending this OSCON is <a href="http://www.oscon.com/oscon2012/public/schedule/detail/23272" target="_blank">Instantly Better Vim</a>.  Another Damian Conway talk, a longer version of which I&#8217;ve previously attended, but let&#8217;s face it&#8230; I still haven&#8217;t adopted most of the Vim tricks he taught me the first time, and I could use a refresher.</p>
<p>Wow&#8230; by the end of this conference, word has gotten around about Damian&#8217;s talks.  He is just too entertaining to miss.  They had to get a second room and pull out the wall to accomodate his final talk.  And as usual he sent me away wanting to try some Vim tricks right away.</p>
<p>Well, that was my OSCON 2012.  As usual, a very well organized event, chock full of learning and networking opportunities, jobs for those that want them, and generalized geeky inspiration.  I often find myself back in the hotel room coding, or tucked away somewhere in the conference hall, slowly exploring some of the new ideas I&#8217;ve been exposed to.  Thanks to UNH for my funding.</p>
]]></content:encoded>
			<wfw:commentRss>http://software.unh.edu/2012/07/16/reports-from-oscon-2012/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Unslow Regexps</title>
		<link>http://software.unh.edu/2012/06/15/unslow-regexps/</link>
		<comments>http://software.unh.edu/2012/06/15/unslow-regexps/#comments</comments>
		<pubDate>Fri, 15 Jun 2012 17:53:25 +0000</pubDate>
		<dc:creator>Paul Sand</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[gut feelings]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[regexp]]></category>

		<guid isPermaLink="false">http://software.unh.edu/?p=1141</guid>
		<description><![CDATA[Our mail logs accumulate a few million lines per weekday. Some of them contain information on whether SpamAssassin considered a given message to be spam: Jun 11 23:58:15 sunapee MailScanner[7997]: Message q5C3vVli019865 from 71.243.115.147 (info@softwareevals.org) to unh.edu is spam, SpamAssassin (not cached, score=15.565, required 5, BAYES_00 -1.90, DIGEST_MULTIPLE 0.29, HELO_DYNAMIC_IPADDR 1.95, HTML_MESSAGE 0.00, KHOP_DNSBL_BUMP 2.00, [...]]]></description>
			<content:encoded><![CDATA[<p>Our mail logs accumulate a few million lines per weekday. Some of them contain information on whether SpamAssassin considered a given message to be spam:</p>
<blockquote><p><tt>Jun 11 23:58:15 sunapee MailScanner[7997]: Message q5C3vVli019865 from 71.243.115.147 (info@softwareevals.org) to unh.edu is spam, SpamAssassin (not cached, score=15.565, required 5, BAYES_00 -1.90, DIGEST_MULTIPLE 0.29, HELO_DYNAMIC_IPADDR 1.95, HTML_MESSAGE 0.00, KHOP_DNSBL_BUMP 2.00, MIME_HTML_ONLY 0.72, PYZOR_CHECK 1.39, RAZOR2_CF_RANGE_51_100 0.50, RAZOR2_CF_RANGE_E8_51_100 1.89, RAZOR2_CHECK 0.92, RCVD_IN_HOSTKARMA_BL 1.70, URIBL_BLACK 1.73, URIBL_JP_SURBL 1.25, URIBL_RHS_DOB 1.51, URIBL_WS_SURBL 1.61)</tt></p></blockquote>
<p>or &#8220;ham&#8221; (not spam):</p>
<blockquote><p><tt>Jun 11 23:59:54 sunapee MailScanner[7634]: Message q5C3xp77020291 from 208.117.48.80 (bounces+54769-353f-cfg6=cisunix.unh.edu@email.news.spotifymail.com) to cisunix.unh.edu is not spam, SpamAssassin (not cached, score=-2, required 5, autolearn=not spam, BAYES_00 -1.90, HTML_MESSAGE 0.00, RCVD_IN_HOSTKARMA_NO -0.09, SPF_PASS -0.00, T_RP_MATCHES_RCVD -0.01)</tt></p></blockquote>
<p>(Lines wrapped for clarity.)</p>
<p>Perl scripts scan through the logs and produce plots of ham/spam traffic, typical example <a href="http://pubpages.unh.edu/~sysman/hourly_ham_spam.png">here</a>. Such scripts need to (for lines like the above) extract the date/time information (always the first 15 characters) and whether the line says &#8220;is spam&#8221; or &#8220;is not spam&#8221;. My initial approach (years ago) was very simple-minded. Old code snippet:</p>
<pre class="brush: perl; title: ; notranslate">
while (&lt;&gt;) {
    if (/is spam/ || /is not spam/) {
        $date = ParseDate(substr($_, 0, 15));
        $dt = UnixDate($date, &quot;%Y-%m-%d %H:00&quot;);
        if (/is spam/) {
             $spamcount{$dt}++;
        else {
             $hamcount{$dt}++;
        }
    }
}
</pre>
<p>(ParseDate and UnixDate are routines from the Date::Manip package. Without getting bogged down in details, they allow the messages to be counted in hour-sized buckets for the plot linked above.)</p>
<p>For not-particularly-important reasons, I decided to try an &#8220;all at once&#8221; regular expression on each line instead. New code snippet:</p>
<pre class="brush: perl; title: ; notranslate">
use Readonly;
use Regexp::Common qw/net/;

Readonly my $SPAMLINE_RE =&gt; qr {
    ^
    (\w{3} \s+ \d+ \s \d{2}:\d{2}:\d{2}) \s
    \w+ \s MailScanner \[\d+\]: \s
    Message \s \w+ \s
    from \s ($RE{net}{IPv4}) \s
    \([^)]*\) \s to \s \S+ \s
    (is \s (?:not \s)? spam)
}x;

while (&lt;&gt;) {
    if ( $_ =~ $SPAMLINE_RE ) {
        my $d        = $1;
        my $spamflag = $3;
        my $date     = ParseDate($d);
        my $dt       = UnixDate( $date, '%Y-%m-%d %H:00' );
        if ( $spamflag eq 'is spam' ) {
            $spamcount{$dt}++;
        }
        else {
            $hamcount{$dt}++;
        }
    }
}
</pre>
<p>There&#8217;s plenty to criticize about both snippets, but mainly I was thinking: running the second version&#8217;s huge, hairy regular expression on each log line will <em>just have</em> to be way slower than the simple fixed-string searching in the first version. (Even though there can be up to three searches per line in the first version, they&#8217;re searches for <em>fixed strings</em>, right? Right?)</p>
<p>Wrong, as it turns out. The hairy second version ran slightly <em>faster</em> than the simple-minded first version. (In addition it extracts the IP address of the server that sent us the message; not used here, but important in other scripts.)</p>
<p>Humbling moral: even after many years of Perl coding, my gut feelings about efficiency are not to be trusted.</p>
]]></content:encoded>
			<wfw:commentRss>http://software.unh.edu/2012/06/15/unslow-regexps/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
