<?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>dagolden &#187; perl programming</title>
	<atom:link href="http://www.dagolden.com/index.php/category/perl-programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dagolden.com</link>
	<description>Whatever comes to mind</description>
	<lastBuildDate>Mon, 23 Jan 2012 03:43:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Perl Oasis 2012 wrapup</title>
		<link>http://www.dagolden.com/index.php/1565/perl-oasis-2012-wrapup/</link>
		<comments>http://www.dagolden.com/index.php/1565/perl-oasis-2012-wrapup/#comments</comments>
		<pubDate>Wed, 18 Jan 2012 03:45:32 +0000</pubDate>
		<dc:creator>dagolden</dc:creator>
				<category><![CDATA[perl programming]]></category>
		<category><![CDATA[conferences]]></category>
		<category><![CDATA[opw]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.dagolden.com/?p=1565</guid>
		<description><![CDATA[Last weekend I attended the Orlando Perl Workshop. While the "hallway track" is one of the best parts of Perl workshops, the talks I saw were also excellent. Here is an overview of the sessions I attended. Doing the Jitterbug Jonathan Leto (dukeleto) presented Jitterbug, a cross language continuous integration tool for git (and written [...]]]></description>
			<content:encoded><![CDATA[<p>Last weekend I attended the Orlando Perl Workshop.  While the "hallway track" is one of the best parts of Perl workshops,  the talks I saw were also excellent.  Here is an overview of the sessions I attended.</p>
<h2>Doing the Jitterbug</h2>
<p>Jonathan Leto (dukeleto) presented <a href="http://jitterbug.pl">Jitterbug</a>, a cross language continuous integration tool for git (and written in Perl).  It's a smaller, lighter tool than Jenkins, though it lacks distributed testing capabilities.  It seems really good for small to medium sized Perl projects, as it already understands how to build and test things with a Makefile.PL or Build.PL.  (<a href="https://github.com/leto/presentations/blob/master/2012/perl_oasis_doing_the_jitterbug/pres.pdf?raw=true">see slides</a> [pdf])</p>
<h2>Javascript is Code</h2>
<p>Jay Shirley (jshirley) gave a non-Perl talk that explained why Javascript tends in practice towards spaghetti code.  He recommended the YUI3 framework and explained why it provides better structure and why it would be familiar to Perl programmers used to Moose.</p>
<h2>A Brave New Perl World</h2>
<p>Stevan Little (stevan) presented some ideas from the work-in-progress prototype of a meta-object protocol (aka MOP) for the Perl 5 core.  I'm really excited by this and I think the design team is finding a pragmatic balance between power and simplicity.</p>
<h2>Tweakers Anonymous</h2>
<p>John Anderson (genehack) gave an editor-agnostic half-rant/half-tutorial about why and how to tweak your editor to be more productive and less repetitive.  There were some good tips that I've already put intro practice, like teaching the editor to automatically "chmod +x" when saving any "*.pl" file. (<a href="http://www.slideshare.net/genehackdotorg/tweakers-anonymous">see slides</a>)</p>
<h2>The First Thing Tak Did - Elegant Remote Control For Sysadmins</h2>
<p>Matt S. Trout (mst) showed an insanely complicated but powerful command line tool to remotely execute any pure Perl code over ssh, without needing any prerequisite modules installed on the remote machine.  It's worth exploring just to understand the magic that makes it work.</p>
<h2>Game Development with Perl &amp; SDL</h2>
<p>Breno Oliveira (garu) gave a playful talk that showed how easy it has become to use Perl to write simple graphical games.  In only a couple dozen lines of code, he demonstrated a simple 2D platform game using the built in physics model. (<a href="http://www.slideshare.net/garux/game-development-with-sdl-and-perl">see slides</a>)</p>
<h2>Cooking Perl with Chef Solo</h2>
<p>This was my talk, where I explained what I've been doing to make it possible to deploy Plack apps using Chef and Perlbrew and friends. (<a href="http://xdg.me/talks/cooking-perl-with-chef/">see slides</a>)</p>
<h2>Lightning talks</h2>
<p>There was the usually assortment of amusing talks, though several presenters thought it would be "fun" to present their 20 minute (or longer) talks in 5 minutes for anyone who missed the original.  (Note to future presenters -- please don't do that.  Pick 5 key slides and just show those.)</p>
<p>The most interesting to me was the lightning talk by Bruce Gray (util), who introduced <a href="http://rosettacode.org/wiki/Rosetta_Code">Rosetta Code</a>, a site that shows how different languages solve hundreds of common programming problems.  He said that Perl needs more solutions written to catch up to other languages, so if you have time and interest then please check it out.</p>
<h2>Keynote</h2>
<p>Cory Watson (gphat) gave a funny talk that in style was nearly worthy of Larry Wall.  It meandered around the broad theme of "diversity" and whether more ways of thinking about things makes one smarter.  It eventually circled back to Perl, but the overall call to action was to get out of the usual comfort zones and try something you haven't done before and aren't good at -- whether radical or minor -- in order to stretch your brain. (I can't do it justice in text -- I think you had to be there.)</p>
<h2>Hackathon</h2>
<p>On Sunday, I went for brunch with some other attendees and then parked myself at the hackathon until it was time to leave for the airport.  While I was there, I sucessfully ported my auto-install CD creation tools to work on Debian ISOs instead of just Ubuntu ISOs, so I can test my Perl/Chef tools on that server platform as well.</p>
<h2>Coda</h2>
<p>As a final note, Chris Prather (perigrin) -- who appeared ably supported by his family -- put on an excellent conference and I want to thank him for the work that went into it.  I hope I can attend again in 2013 and recommend it to anyone who wants to get away and have some fun with Perl in the dark of January.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagolden.com/index.php/1565/perl-oasis-2012-wrapup/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Yet another taint mode reminder</title>
		<link>http://www.dagolden.com/index.php/1560/yet-another-taint-mode-reminder-to-use-taint-mode-if-you-care-about-security/</link>
		<comments>http://www.dagolden.com/index.php/1560/yet-another-taint-mode-reminder-to-use-taint-mode-if-you-care-about-security/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 16:56:20 +0000</pubDate>
		<dc:creator>dagolden</dc:creator>
				<category><![CDATA[perl programming]]></category>
		<category><![CDATA[ironman]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://www.dagolden.com/?p=1560</guid>
		<description><![CDATA[Schwern just posted "How (not) To Load a Module..." that goes into great depth about the security risk in loading modules. The (not) funny thing is that none of what he's saying is a risk would be one when running in taint mode. Consider "/tmp/foo.pm" with this: Then consider this example of how Module::Load does [...]]]></description>
			<content:encoded><![CDATA[<p>Schwern just posted <a href="http://blogs.perl.org/users/michael_g_schwern/2011/10/how-not-to-load-a-module-or-bad-interfaces-make-good-people-do-bad-things.html">"How (not) To Load a Module..."</a> that goes into great depth about the security risk in loading modules.</p>
<p>The (not) funny thing is that none of what he's saying is a risk would be one when running in taint mode.</p>
<p>Consider "/tmp/foo.pm" with this:</p>
<pre class="brush: perl; title: ; notranslate">
package foo;
print &quot;Loaded foo\n&quot;;
1;
</pre>
<p>Then consider this example of how Module::Load does something "unexpected":</p>
<pre class="brush: plain; title: ; notranslate">
$ perl -MModule::Load=load -wE 'my $file=shift; load $file' ::tmp::foo
Loaded foo
</pre>
<p>(The "threat" is that given an arbitrary module name to load, it will gladly load outside <code>@INC</code>.)</p>
<p>What if that was run under taint mode, instead?</p>
<pre class="brush: plain; title: ; notranslate">
$ perl -MModule::Load=load -wTE 'my $file=shift; load $file' ::tmp::foo
Insecure dependency in require while running with -T switch at /home/david/perl5/perlbrew/perls/perl-5.14.0/lib/5.14.0/Module/Load.pm line 27.
Insecure dependency in require while running with -T switch at /home/david/perl5/perlbrew/perls/perl-5.14.0/lib/5.14.0/Module/Load.pm line 27.
</pre>
<p>I'm not sure why that message is printed twice, but that was still a fatal error and foo.pm didn't load.</p>
<p>The moral of the story: <strong>if you incorporate arbitrary user input into your execution path, use taint mode and validate the input to make sure it's something safe.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagolden.com/index.php/1560/yet-another-taint-mode-reminder-to-use-taint-mode-if-you-care-about-security/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>How to find files with Path::Class::Rule</title>
		<link>http://www.dagolden.com/index.php/1552/how-to-find-files-with-pathclassrule/</link>
		<comments>http://www.dagolden.com/index.php/1552/how-to-find-files-with-pathclassrule/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 01:38:37 +0000</pubDate>
		<dc:creator>dagolden</dc:creator>
				<category><![CDATA[perl programming]]></category>
		<category><![CDATA[ironman]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.dagolden.com/?p=1552</guid>
		<description><![CDATA[Path::Class::Rule is what you get when you imagine the love-child of Path::Class and File::Find::Rule. Here is part of the SYNOPSIS: As you can see, it has the same method-chaining of rule helpers that File::Find::Rule does. However, it's not built on top of File::Find, so you get a real, lazy iterator instead of the File::Find::Rule iterator [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://p3rl.org/Path::Class::Rule" title="Path::Class::Rule" target="_blank">Path::Class::Rule</a> is what you get when you imagine the love-child of <a href="http://p3rl.org/Path::Class::Rule" title="Path::Class" target="_blank">Path::Class</a> and <a href="http://p3rl.org/File::Find::Rule" title="File::Find::Rule" target="_blank">File::Find::Rule</a>.  Here is part of the SYNOPSIS:</p>
<pre class="brush: perl; title: ; notranslate">
use Path::Class::Rule;

my $rule = Path::Class::Rule-&gt;new; # match anything
$rule-&gt;file-&gt;size(&quot;&gt;10k&quot;);         # add/chain rules

# iterator interface
my $next = $rule-&gt;iter( @dirs );
while ( my $file = $next-&gt;() ) {   # $file is a Path::Class object
  ...
}
</pre>
<p>As you can see, it has the same method-chaining of rule helpers that File::Find::Rule does.  However, it's not built on top of <a href="http://p3rl.org/File::Find" title="File::Find" target="_blank">File::Find</a>, so you get a real, lazy iterator instead of the File::Find::Rule iterator that precomputes the results and hands them to you one at a time. The iterator returns Path::Class objects, which makes it a little easier to do some common file manipulations.</p>
<p>While Path::Class::Rule is very new, it already implements the following kinds of rule helpers:</p>
<ul>
<li>File name rules</li>
<li>Directory skipping rules</li>
<li>File test rules, e.g. -f, -d, -r, -w, etc.</li>
<li>Stat test rules, e.g. results of stat()</li>
<li>Search depth rules</li>
<li>Perl file rules</li>
<li>Version control file skipping rules</li>
</ul>
<p>It's also easy to extend.  You only need to "and" together a callback that gets <code>$_</code> set to the Path::Class object under examination:</p>
<pre class="brush: perl; title: ; notranslate">
$rule-&gt;and( sub { -r -w -x $_ } ); # stacked filetest example
</pre>
<p>You can write extension classes with new helper methods using the <code>add_helper</code> method.  Here's a simple example that matches files named "foo":</p>
<pre class="brush: perl; title: ; notranslate">
package Path::Class::Rule::Foo;

use Path::Class::Rule;

Path::Class::Rule-&gt;add_helper(
  foo =&gt; sub {
    my @args = @_; # do this to customize closure with arguments
    return sub {
      my ($item) = shift;
      return if $item-&gt;is_dir;
      return $item-&gt;basename =~ /^foo$/;
    }
  }
);

1;
</pre>
<p>If this module sounds interesting, give it a try!  If you want to help improve it, <a href="https://github.com/dagolden/path-class-rule" title="Path::Class::Rule on github" target="_blank">fork it on Github</a> and let me know what you have in mind.</p>
<p>(If you're a curmudgeon and want to know why I wrote <em>another</em> file-finding module for CPAN, read the "SEE ALSO" section of the documentation for my comparison to other things out there.)</p>
<p><b>Update</b> I've released 0.004 with some additional SEE ALSO entries based on suggestions below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagolden.com/index.php/1552/how-to-find-files-with-pathclassrule/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Giving thanks as thanks</title>
		<link>http://www.dagolden.com/index.php/1543/giving-thanks-as-thanks/</link>
		<comments>http://www.dagolden.com/index.php/1543/giving-thanks-as-thanks/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 19:06:26 +0000</pubDate>
		<dc:creator>dagolden</dc:creator>
				<category><![CDATA[perl programming]]></category>
		<category><![CDATA[ironman]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.dagolden.com/?p=1543</guid>
		<description><![CDATA[Ricardo wrote an article "promoting little gifts", which @perlbuzz tweeted as "giving little gifts as thanks". I like that idea, and it inspired me to remind people to please also consider just giving "thanks", too. Sure, I'd love a song or a small ebook (and maybe I should set up a wishlist), but I also [...]]]></description>
			<content:encoded><![CDATA[<p>Ricardo wrote an article <a href="http://rjbs.manxome.org/rubric/entry/1906">"promoting little gifts"</a>, which <a href="https://twitter.com/#!/perlbuzz">@perlbuzz</a> tweeted as <a href="https://twitter.com/#!/perlbuzz/status/106377273384505344">"giving little gifts as thanks"</a>.</p>
<p>I like that idea, and it inspired me to remind people to please also <strong>consider just giving "thanks", too</strong>.</p>
<p>Sure, I'd love a song or a small ebook (and maybe I should set up a wishlist), but <strong>I also love getting an email saying thanks</strong>, particularly when it is from someone I don't already know telling me that they like a module I released to CPAN or telling me how they are using my code to solve some problem they have.  <strong>Email is cheap, but still has huge impact</strong>.</p>
<p>Perl is a community built on altruism.  Don't forget to say thank you!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagolden.com/index.php/1543/giving-thanks-as-thanks/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Code munging with vim: if modifier to if block</title>
		<link>http://www.dagolden.com/index.php/1539/code-munging-with-vim-if-modifier-to-if-block/</link>
		<comments>http://www.dagolden.com/index.php/1539/code-munging-with-vim-if-modifier-to-if-block/#comments</comments>
		<pubDate>Wed, 24 Aug 2011 15:16:19 +0000</pubDate>
		<dc:creator>dagolden</dc:creator>
				<category><![CDATA[perl programming]]></category>
		<category><![CDATA[ironman]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.dagolden.com/?p=1539</guid>
		<description><![CDATA[Not infrequently, I discover I want to turn an if modifier into an if block so I can add extra logic when the conditional is true. I decided to automate that with a vim macro: For it to work, the if modifier has to be on a line of its own (which I usually do [...]]]></description>
			<content:encoded><![CDATA[<p>Not infrequently, I discover I want to turn an if modifier into an if block so I can add extra logic when the conditional is true.</p>
<pre class="brush: perl; title: ; notranslate">
# from this
do_something()
  if condition();

# to this
if ( condition() ) {
  do_something();
}
</pre>
<p>I decided to automate that with a vim macro:</p>
<pre class="brush: plain; title: ; notranslate">
map ,if V:s/\(\s*\)  if \(.*\);/\1if (\2) {/&lt;CR&gt;kVdp&gt;&gt;$a;&lt;CR&gt;&lt;BS&gt;}&lt;CR&gt;&lt;Esc&gt;kkk^
</pre>
<p>For it to work, the if modifier has to be on a line of its own (which I usually do for code clarity) and the cursor needs to be on that line when running the macro.</p>
<p>Feel free to copy and adapt to your own needs and preferences.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagolden.com/index.php/1539/code-munging-with-vim-if-modifier-to-if-block/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Five ways to install module prereqs by hand</title>
		<link>http://www.dagolden.com/index.php/1528/five-ways-to-install-modules-prereqs-by-hand/</link>
		<comments>http://www.dagolden.com/index.php/1528/five-ways-to-install-modules-prereqs-by-hand/#comments</comments>
		<pubDate>Sun, 14 Aug 2011 03:19:58 +0000</pubDate>
		<dc:creator>dagolden</dc:creator>
				<category><![CDATA[perl programming]]></category>
		<category><![CDATA[toolchain]]></category>
		<category><![CDATA[ironman]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.dagolden.com/?p=1528</guid>
		<description><![CDATA[Have you ever tried installing a CPAN module's dependencies by hand? Imagine that you've downloaded a strange tarball or cloned a strange module repository. Running "perl Makefile.PL" or "perl Build.PL" gives you a long list of missing dependencies. How do you quickly install all those dependencies? Here are some options. See the last for a [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever tried installing a CPAN module's dependencies by hand?  Imagine that you've downloaded a strange tarball or cloned a strange module repository. Running "perl Makefile.PL" or "perl Build.PL" gives you a long list of missing dependencies.  How do you quickly install all those dependencies?</p>
<p>Here are some options.  See the last for a new way that I just cooked up and released to CPAN.</p>
<h2>Use your favorite CPAN client against the current directory</h2>
<p>Example:</p>
<pre class="brush: plain; title: ; notranslate">
$ cpan .
</pre>
<p>Beware that this also installs the module in the current directory, which may not be what you want.</p>
<p>cpanminus is smarter than that if you give it an option</p>
<pre class="brush: plain; title: ; notranslate">
$ cpanm --installdeps .
</pre>
<h2>For Module::Build-based modules: Build installdeps</h2>
<p>Example:</p>
<pre class="brush: plain; title: ; notranslate">
$ perl Build.PL
$ Build installdeps
</pre>
<h2>For (some) Module::Install-based modules: make installdeps</h2>
<p>Example:</p>
<pre class="brush: plain; title: ; notranslate">
$ perl Makefile.PL
$ make installdeps
</pre>
<p>Note that this requires the Makefile.PL to use the 'auto_install' plugin.</p>
<h2>For Dist::Zilla-based modules: dzil listdeps</h2>
<p>Example:</p>
<pre class="brush: plain; title: ; notranslate">
$ dzil listdeps | cpanm
# or
$ cpan $(dzil listdeps)
</pre>
<p>This requires installing Dist::Zilla any any dist.ini dependencies first:</p>
<pre class="brush: plain; title: ; notranslate">
$ cpanm Dist::Zilla
$ dzil authordeps | cpanm
</pre>
<p>(Notice a pattern here?)</p>
<h2>Anything with Makefile.PL or Build.PL: MYMETA and mymeta-requires</h2>
<p>Install the latest ExtUtils::MakeMaker, Module::Build and <a href="http://p3rl.org/App::mymeta_requires">App::mymeta_requires</a>.  Then configure as usual and run 'mymeta-requires' to get a list of dependencies.</p>
<p>Example:</p>
<pre class="brush: plain; title: ; notranslate">
$ perl Makefile.PL
$ mymeta-requires | cpanm
# or
$ cpan $(mymeta-requires)
</pre>
<p>A nice feature of 'mymeta-requires' is that it gives you access to all the different prerequisite types defined in the <a href="http://p3rl.org/CPAN::Meta::Spec">CPAN::Meta::Spec</a>.  So if a module offers 'develop' prerequisites, you can include those like this:</p>
<pre class="brush: plain; title: ; notranslate">
$ mymeta-requires --develop | cpanm
</pre>
<p>See the documentation for other ways to control which prerequisites are included in the output.</p>
<p><del datetime="2011-08-14T11:41:59+00:00">One drawback is that you'll still need to install any configuration prerequisites needed to run Makefile.PL or Build.PL, but that is true of all other recipes above (except that ones that use a CPAN client).</del></p>
<p><strong>Update:</strong> as of version 0.002, 'mymeta-requires' will fallback to a META.json|yml file and also picks up configuration prerequisites.  So now you can bootstrap completely like this:</p>
<pre class="brush: plain; title: ; notranslate">
# get configuration prerequisites
$ mymeta-requires | cpanm

# run configuration
$ perl Makefile.PL

# get any additional dynamic prerequisites from configuration
$ mymeta-requires | cpanm
</pre>
<p>Easy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagolden.com/index.php/1528/five-ways-to-install-modules-prereqs-by-hand/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>What are your top binary library dependencies?</title>
		<link>http://www.dagolden.com/index.php/1523/what-are-your-top-binary-library-dependencies/</link>
		<comments>http://www.dagolden.com/index.php/1523/what-are-your-top-binary-library-dependencies/#comments</comments>
		<pubDate>Wed, 27 Jul 2011 00:59:53 +0000</pubDate>
		<dc:creator>dagolden</dc:creator>
				<category><![CDATA[perl programming]]></category>
		<category><![CDATA[ironman]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.dagolden.com/?p=1523</guid>
		<description><![CDATA[On the #toolchain IRC channel, jawnsy and I were discussing how cool it would be if there were Alien::* packages for the top 10 or so binary libraries that people use with Perl. I.e. things like libssl, libxml2, libexpat, etc. I don't know what it would take to make that happen, because getting Alien packages [...]]]></description>
			<content:encoded><![CDATA[<p>On the <a href="irc://irc.perl.org/#toolchain" title="#toolchain" target="_blank">#toolchain</a> IRC channel, <a href="http://jawnsy.wordpress.com" title="jawnsy" target="_blank">jawnsy</a> and I were discussing how cool it would be if there were <a href="http://p3rl.org/Alien" target="_blank">Alien::*</a> packages for the top 10 or so binary libraries that people use with Perl.  I.e. things like libssl, libxml2, libexpat, etc.</p>
<p>I don't know what it would take to make that happen, because getting Alien packages right across platforms is tricky, but a first step is figuring out what libraries people wind up needing the most.</p>
<p><strong>If you install libraries/headers by hand, what do you wind up using most often?</strong>  Please answer in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagolden.com/index.php/1523/what-are-your-top-binary-library-dependencies/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Sorting photos by timestamp with Perl</title>
		<link>http://www.dagolden.com/index.php/1508/sorting-photos-by-timestamp-with-perl/</link>
		<comments>http://www.dagolden.com/index.php/1508/sorting-photos-by-timestamp-with-perl/#comments</comments>
		<pubDate>Sun, 24 Jul 2011 01:04:10 +0000</pubDate>
		<dc:creator>dagolden</dc:creator>
				<category><![CDATA[perl programming]]></category>
		<category><![CDATA[ironman]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.dagolden.com/?p=1508</guid>
		<description><![CDATA[My digital picture frame does a slideshow in filename order. I have hundreds of pictures taken over several years on different cameras with different file naming schemes. I've even rolled over the counter on one of the cameras, so I might have IMG1234.jpg twice (saved in different directories). Here's how I used Perl to rename [...]]]></description>
			<content:encoded><![CDATA[<p>My digital picture frame does a slideshow in filename order.  <strong>I have hundreds of pictures taken over several years on different cameras with different file naming schemes.</strong> I've even rolled over the counter on one of the cameras, so I might have IMG1234.jpg twice (saved in different directories).</p>
<p><strong>Here's how I used Perl to rename these pictures</strong> into the right order based on the timestamp metadata inside the JPEG files:</p>
<pre class="brush: perl; title: ; notranslate">
#!/usr/bin/env perl
use 5.010;
use strict;
use warnings;
use autodie;
use Digest::MD5 'md5_hex';
use Image::ExifTool 'ImageInfo';
use Path::Class;

for my $f ( dir()-&gt;children ) {
  next if $f-&gt;is_dir;
  my $exif = Image::ExifTool-&gt;new;
  $exif-&gt;ExtractInfo($f-&gt;stringify);
  my $date = $exif-&gt;GetValue('DateTimeOriginal', 'PrintConv');
  next unless defined $date;
  $date =~ tr[ :][T-];
  my $digest = md5_hex($f-&gt;slurp);
  $digest = substr($digest,0,7);
  my $new_name = &quot;$date-$digest.jpg&quot;;
  unless ( $f-&gt;basename eq $new_name ) {
    rename $f =&gt; $new_name;
    say &quot;renamed $f =&gt; $new_name&quot;;
  }
}
</pre>
<p>This program renames everything in the current directory into a format like this "2011-05-28T14-48-20-7fc2e71.jpg" -- which is an ISO8601 datetime (with "-" instead of ":") plus the first 7-hex-characters of an MD5 checksum.  I use the checksum on the off-chance that two pictures were taken at the exact same second (e.g. from two cameras) or that one picture was a cropped/retouched version of an original.  Anything that doesn't have EXIF datetime information is skipped and then I have to examine those manually to sort them into the rest.</p>
<p>It's not much, but it's quick and it worked.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagolden.com/index.php/1508/sorting-photos-by-timestamp-with-perl/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Counterfactual Perl 6</title>
		<link>http://www.dagolden.com/index.php/1492/counterfactual-perl/</link>
		<comments>http://www.dagolden.com/index.php/1492/counterfactual-perl/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 03:19:34 +0000</pubDate>
		<dc:creator>dagolden</dc:creator>
				<category><![CDATA[p5p]]></category>
		<category><![CDATA[perl programming]]></category>
		<category><![CDATA[perl6]]></category>
		<category><![CDATA[ironman]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.dagolden.com/?p=1492</guid>
		<description><![CDATA[Several recent posts (more here and here) discuss whether Perl 6 is an impediment for progress of Perl 5 and debate remedies involving changing the name of one or the other. The problem I have with these debates is that they sideline the realities of the current situation in favor of romanticizing a counterfactual. The [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://j.mp/mQj6Et">Several</a> <a href="http://j.mp/koCnP0">recent</a> <a href="http://j.mp/jqxfRT">posts</a> (more <a href="http://j.mp/mxhLan">here</a> and <a href="http://j.mp/k5iE5S">here</a>) discuss whether Perl 6 is an impediment for progress of Perl 5 and debate remedies involving changing the name of one or the other.  <strong>The problem I have with these debates is that they sideline the realities of the current situation in favor of romanticizing a counterfactual</strong>.</p>
<p>The counterfactual is this: <strong><em>"If Perl 6 never existed, then Perl 5 could bump itself to Perl 6 NOW in order to signal a backwards-incompatible break from the past."</em></strong></p>
<p>If the counterfactual were true, I believe this could happen, even with the limitations of the Perl 5 development process we have today.  Perl 6 (as it actually does exist today) is revolutionary design, not evolutionary design, but that doesn't preclude an evolution of Perl 5 that significantly breaks backwards compatibility.</p>
<p>Without recommending any particular change,<strong> here are some examples of things that I think could be possible</strong>, just to give a sense of what evolutionary (rather than revolutionary) changes could attempt:</p>
<ul>
<li>Replacing <code>eval BLOCK</code> syntax with <code>try BLOCK</code></li>
<li>Removing of Unix-specific user/group functions and similar cruft</li>
<li>Eliminating of indirect syntax</li>
<li>Replacing method call arrow <code>-></code> with the shorter (and more widely recognized) dot/period character (and finding a new concatenation operator)</li>
<li>Eliminating version objects and v-strings</li>
<li>Replacing (frequently misunderstood) function prototypes with function signatures</li>
</ul>
<p>Those are just ideas off the top of my head, but I hope it's easy to see than a<strong>ny of those break enough existing code as to make them very difficult to envision being added to any future release of Perl 5</strong>.  However, if the counterfactual were true, then there would always be the option of making a clean break to "Perl 6", ensuring that there is no automatic expectation of backwards compatibility.</p>
<p><strong>Even if the counterfactual were true, making such evolutionary changes would not necessarily be easy.</strong>  It would require a Pumpking (other than Larry Wall) to play language designer for Perl 5 and to push the Perl core developer community into a rough consensus.  But hard does not mean impossible.</p>
<p>However, with the reality of Perl 6 as it stands, even a name change by Perl 6 ("Camelia" was one suggestion) doesn't help Perl 5's evolution.  Given the expectations that have been set for Perl 5, it seems unlikely to me that there would be broad community support for Perl 5 evolving into Perl 6 if Perl 6 were renamed.  <strong>"Hi, we promised you Perl 6 ten years ago, but it's not ready for production, so we're going to call this other thing Perl 6 instead."</strong>  I don't think that's great for external perceptions, either.  What then?  Jump over Perl 6 straight to Perl 7?  I don't think that would be well received, either.</p>
<p>For Perl 5 to evolve in ways that are significantly backwards-incompatible, I see only two realistic options:</p>
<ul>
<li><strong>Rename Perl 5 to something else</strong>, with all the associated branding and marketplace traction issues that would cause, but with the ability to make a major version number bump to manage compatibility expectations.</li>
<li><strong>Increase the speed of mutation of Perl 5</strong> so that Versions 16, 18, 20, etc. become bigger departures cumulatively than we ever saw with Versions 6, 8, 10, etc., and become much more ruthless about setting future compatibility expectations.</li>
</ul>
<p><em>(I suppose an interesting variation on the first way would be for Perl 5 <em>and</em> Perl 6 to be renamed simultaneously.  I could see that having some positive opportunities for branding and marketing.)</em></p>
<p><strong>The status quo alternative is for Perl 5 and Perl 6 to continue as they have been, slowly chugging along on their respective tracks</strong>.  Perl 5 will continue to put backwards compatibility over evolution and won't see substantial new features added or old mis-features cleaned up.  Perl 6 will continue to push towards some sort of production readiness.  </p>
<p>For some (perhaps many), the status quo is ideal.  For me, I would find it rather boring to be a part of.</p>
<p>So -- let <strong>that</strong> be the real debate in the Perl 5 community: <strong>compatibility</strong> or <strong>evolution</strong>?  Names and version numbers are just the means to an end. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagolden.com/index.php/1492/counterfactual-perl/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Throwing in the towel</title>
		<link>http://www.dagolden.com/index.php/1486/throwing-in-the-towel/</link>
		<comments>http://www.dagolden.com/index.php/1486/throwing-in-the-towel/#comments</comments>
		<pubDate>Sun, 22 May 2011 03:27:46 +0000</pubDate>
		<dc:creator>dagolden</dc:creator>
				<category><![CDATA[meta]]></category>
		<category><![CDATA[perl programming]]></category>
		<category><![CDATA[ironman]]></category>

		<guid isPermaLink="false">http://www.dagolden.com/?p=1486</guid>
		<description><![CDATA[A little over two years ago, I accepted the Perl Iron Man challenge. I found the challenge inspirational, and did a lot more blogging about projects I was working on than I would have otherwise. Hopefully, those who read my posts found them helpful, or at least interesting enough for the time it took to [...]]]></description>
			<content:encoded><![CDATA[<p>A little over two years ago, <a href="http://www.dagolden.com/index.php/28/iron-man-challenge-accepted/">I accepted the Perl Iron Man challenge</a>.  I found the challenge inspirational, and did a lot more blogging about projects I was working on than I would have otherwise.  Hopefully, those who read my posts found them helpful, or at least interesting enough for the time it took to read them.</p>
<p>However, as I reflect on the doubling of my parental responsibilities and a pending shift to more entrepreneurial employment, I've decided to throw in the towel on Iron Man.  I plan to keep blogging, but probably not at the pace I've been, nor always about Perl.  I have new challenges in front of me and new projects in mind to tackle them.  Of course, when they involve Perl, i'll be sure to mention it.</p>
<p>Stay tuned...</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagolden.com/index.php/1486/throwing-in-the-towel/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

