LTjake's Journal LTjake's use Perl Journal en-us use Perl; is Copyright 1998-2006, Chris Nandor. Stories, comments, journals, and other submissions posted on use Perl; are Copyright their respective owners. 2012-01-25T02:10:36+00:00 pudge Technology hourly 1 1970-01-01T00:00+00:00 LTjake's Journal File::HomeDir 0.91 data directory changes <p>After performing a routine upgrade of my CPAN modules on my $work machine, I noticed that I was prompted to configure CPAN for the first time after I attempted to load the CPAN shell again.</p><p>Obviously I had already done all of that so I had to figure out what had changed. I remembered having installed only a couple new modules, including File::HomeDir.</p><p>Browsing its Changes file shows:</p><blockquote><div><p>Moving the FreeDesktop driver to prod</p></div> </blockquote><p>My operating system is Ubuntu 10.04, which apparently means that File::HomeDir will use these new FreeDesktop rules. The big change is that the default data dir is no longer your home directory, but <strong>~/.local/share/</strong> </p><p>The simple fix was to move my<nobr> <wbr></nobr>.cpan dir to ~/.local/share/. From then on, everything worked as per usual. This will also affect any other apps that use File::HomeDir to locate your data dir, including Padre.</p> LTjake 2010-06-03T15:33:46+00:00 journal Project Stepping Stones <p>Ever looked back at something you&#39;ve worked on and thought: &quot;Gee, it&#39;s too bad that project didn&#39;t get to it&#39;s ultimate goal, but, I&#39;ve learned a lot from it.&quot; I have one of those projects. Such is the world of technology, your toolset is constantly evolving and shape-shifting; even &quot;The Next Big Thing&quot; can become obsolete. We move on to the next &quot;Next Big Thing.&quot;</p><p>One such area in the Web Developer&#39;s toolset is &quot;Search.&quot; I&#39;m sure we can all relate to the experience of our first textbox with some behind-the-scenes code doing SQL &quot;SELECT<nobr> <wbr></nobr>... LIKE&quot; statements. Perhaps at first it was raw DBI calls; maybe moving on to an abstraction layer (ORM and whatnot) shortly thereafter. Here&#39;s where things get interesting.</p><p>What happens when this is no longer Good Enough(tm). Google being essentially ubiquitous, people expect to plunk some words in the box and magically get what they want out the other side. I put in &quot;Cat Hat&quot; -- why didn&#39;t it give me &quot;Cat in the Hat&quot;? Okay, no problem. We can do some field and query normalization; removing stopwords, add term parsing<nobr> <wbr></nobr>... wait, wait wait. There has to be prior art for this.</p><p>In 2004, the options are somewhat limited as far as Free/Open Source search software goes. Especially in Perl land. <a href="">Swish-e</a> looks pretty neat. We actually did some prototyping with it. It was definitely a step ahead of plain old SQL. <a href="">Plucene</a> came on the scene. Unfortunately, it&#39;s poor performance was a bit of a non-starter for us. The fact that it was modeled after the <a href="">Lucene Java library</a>, however, caught my eye.</p><p>I wanted to harness their project and its community, and bring it into our little Perl world. Luckily for me, someone else had already started down that road. The Lucene Web Service was a project by Robert Kaye, sponsored by CD Baby, which allowed users to talk to Lucene via an XML-based web service. After using it for a while, we developed some patches for bug fixes and enhancements. Because of our momentum with the project, we were eventually given total control over its development.</p><p>We attempted to strengthen the project by hooking into some existing standards. We leveraged the <a href="">Atom Publishing Protocol</a> as an analogy for dealing with indexes and documents. Search results were returned as an <a href="">OpenSearch</a> document. A document&#39;s field-value pairs were listed in the <a href="">XOXO microformat</a>. Creating a client for this setup meant a bunch of glue between the existing components (<a href="">XML::Atom::Client</a> and <a href="">WWW::OpenSearch</a>).</p><p>Almost in parallel, the <a href="">Solr project</a> emerged. Similar idea, much more support behind it. In the end, our idea never got very far, and Solr has turned out to be a fabulous product -- which we now use.</p><p>To this end, the <a href="">Lucene WebService website</a> will (finally) be shutting down in about a week&#39;s time. I&#39;ve moved the pertinent code and wiki data to <a href="">github</a> in case anyone wants it. I still think it has some niche applications, but without some serious revamping of the java code, it will likely just rot.</p><p>At least it&#39;s a project that has led me to bigger and better things. </p> LTjake 2010-02-03T21:04:44+00:00 journal New Padre-Plugin-PerlTidy release <p> <a href="">Padre 0.54</a> introduced a couple of project-specific settings, one for Perl::Critic and another for Perl::Tidy. As the maintainer of the <a href="">Perl::Tidy plugin</a>, it was only natural that I should implement support for this new feature.</p><p>Unfortunately, it wasn&#39;t immediately obvious to me how I might get at this info. With Adam&#39;s guidance, I was able to write the following:</p><blockquote><div><p>my $tidyrc = $self-&gt;current-&gt;document-&gt;project-&gt;config-&gt;config_perltidy;</p></div> </blockquote><p>It&#39;s a mess of chained method calls, but, it pretty clear that we&#39;re getting the current document&#39;s project-related config, if it exists.</p><p>Here&#39;s a screenshot of the new version of the plugin in action.</p><p>[<a href="">Image</a>]</p><p> <a href="">Grab version 0.09 from CPAN now.</a> </p> LTjake 2010-01-15T14:47:50+00:00 journal The last five months <p>I haven&#39;t bothered to post anything in the last five months. With Christmas just around the corner, I figure this is as good a time as any to play catch up.</p><p> <strong>Padre-Plugin-PerlTidy</strong></p><ul> <li>A new release of this plugin -- changes made mostly by other people.</li></ul><p> <strong>Gedcom-FOAF</strong></p><ul> <li>Rather than using a base url for the data, you can now specify a number of url templates. This makes the module actually useful. Thanks to Chris Prather for working through this with me.</li></ul><p> <strong>Geo-IPfree</strong></p><ul> <li>A couple of releases with various refactoring bits and bug fixes. The folks at now produce a data file specifically for this module. I will ship an updated copy with every release. Refactoring this code has been pretty satisfying, though there are some parts of the module API which I detest but I will be unable to modify them.</li></ul><p> <strong>Image-Textmode/Image-Textmode-Reader-ANSI-XS</strong></p><ul> <li>Various bug fixes thanks to some testing with a large dataset from Doug Moore and</li></ul><p> <strong>Config-Any</strong></p><ul> <li>Released version 0.18, which prefers YAML::XS over any other YAML parser. This created a number of issues with the HTML::FormFu crowd as existing parsers allowed this sort of syntax &quot;auto_id: %n&quot; -- whereas YAML::XS complains about an exposed percent sign. The easy fix is to wrap the string in quotes &quot;auto_id: &#39;%n&#39;&quot;</li></ul><p> <strong>GD-Image-Scale2x</strong></p><ul> <li>Fixed a nasty bug due to a missing my() which randomly broke the module on some platforms.</li></ul><p> <strong>CGI-Application-PhotoGallery</strong></p><ul> <li>A tiny patch for max_height included in this release. This still has some pending issues in RT -- though I have a hard time justifying spending any time on them as I don&#39;t use this module at all.</li></ul><p> <strong>Catalyst-Model-WebService-Solr</strong></p><ul> <li>Apparently, this module was basically broken. Fixed thanks to a supplied patch.</li></ul><p> <strong>Template-Provider</strong></p><ul> <li>Another kind user supplied some patches/info to support mod_perl and fully qualified template names.</li></ul><p> <strong>CQL-Parser/SRU</strong></p><ul> <li>Removing use of UNIVERSAL-&gt;import from these module. Not even sure why it was there to begin with.</li></ul><p> <strong>WebService-Solr</strong></p><ul> <li>A couple of release of this module. Includes some bug fixes, feature additions and Solr 1.4 compatibility.</li></ul><p> <strong>Remove auto_install from my dists</strong></p><ul> <li>Although, as I understand it, auto_install now works in newer versions of Module::Install, I&#39;ve decided to remove it from my dists to avoid any issues.</li></ul><p>See you next year.</p> LTjake 2009-12-18T19:05:48+00:00 journal Adding a feature to Padre <p>I&#39;ve been following (and even contributing to) the <a href="">Padre IDE</a> project from very early on. I&#39;ve watched it grow from very modest beginings into something quite impressive -- usable, even.</p><p>Its deep integration with Perl is such a killer feature. There are already a good <a href=";mode=dist">two-dozen plugins</a>, one of which I&#39;ve been shepherding: <a href="">Padre-Plugin-PerlTidy</a>.</p><p>In light of Padre&#39;s first birthday, I decided I wanted to give something back into the Padre core rather than just an ancillary project.</p><p>I tend to use gedit on Ubuntu, and I rather liked the &quot;right margin&quot; option. This option puts a gray vertical line on whichever column you specify. It&#39;s an easy visual queue for long lines. It turns out that the Scintilla editor component supports this feature and all I had to do was enable the menus and dialogs to allow users to toggle the method.</p><p>[<a href="">Padre with &quot;right margin&quot; option</a>]</p><p>...and there you have it. It didn&#39;t take very long, and it&#39;s not exactly mind blowing, but it&#39;s something I&#39;ve found useful.</p> LTjake 2009-07-28T12:25:56+00:00 journal Dear Module Author <p>Dear Module Author,</p><p>When preparing to upload a new release of your module to PAUSE could you please review your Changes file?</p><p>Did you remember to update it? Does it contain something meaningful? Here are a couple of examples of Changes entries which mean very little to me at a glance:</p><ul> <li>Bug Fixed</li><li>Foo::Bar Fixed</li><li>Fixed RT #12345</li></ul><p>Also, your SCM revision log does not a good Changes file make.</p><p>Yes, this is old news. This is just a reminder. </p> LTjake 2009-06-03T19:43:31+00:00 journal Elsewhere <p>This is just a quick note to let y&#39;all know that I now have a <a href="">twitter account</a> and an <a href=""> account</a>.</p><p>You have been warned.</p> LTjake 2009-05-26T17:57:59+00:00 journal Benchmark <p>As noted in my <a href="">last post</a>, I was able to get a bit of a speed boost based on observations made as a result of code profiling.</p><p>In general, if I want to see if one piece of code is faster than another, I use <a href="">Benchmark</a>. Benchmark is shipped as part of the core set of modules, so there&#39;s no need to load up CPAN to get started. Its simplest usage, and the one i prefer looks something like this:</p><blockquote><div><p>&#160;&#160;&#160; use Benchmark ();<br>&#160;&#160; &#160;<br>&#160;&#160;&#160; Benchmark::cmpthese( $count, {<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Foo1 =&gt; sub {<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; # code to do Foo1 here<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; },<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Foo2 =&gt; sub {<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; # code to do Foo1 here<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; },<br>&#160;&#160;&#160; } );</p></div> </blockquote><p>Of note is that $count can be negative, which will then signify how many seconds to run instead of the number of times. The result looks like this:</p><blockquote><div><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Rate Foo1 Foo2<br>&#160;&#160;&#160; Foo1 108665/s&#160;&#160; -- -38%<br>&#160;&#160;&#160; Foo2 175460/s&#160; 61%&#160;&#160; --</p></div> </blockquote><p>It&#39;s pretty easy to see that Foo2 was faster. Using the above it was easy for me to test the XS-based ANSI parser vs the pure Perl version.</p><p>4k worth of ANSI over 10 seconds yields the following:</p><blockquote><div><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Rate&#160;&#160;&#160; PP&#160;&#160;&#160; XS<br>&#160;&#160;&#160; PP 15.7/s&#160;&#160;&#160; --&#160; -96%<br>&#160;&#160;&#160; XS&#160; 379/s 2316%&#160;&#160;&#160; --</p></div> </blockquote><p>For giggles, i tested it against a 33k ANSI, giving:</p><blockquote><div><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Rate&#160;&#160;&#160; PP&#160;&#160;&#160; XS<br>&#160;&#160;&#160; PP 2.23/s&#160;&#160;&#160; --&#160; -96%<br>&#160;&#160;&#160; XS 58.7/s 2528%&#160;&#160;&#160; --</p></div> </blockquote><p>Looks like a success to me!</p> LTjake 2009-05-21T17:33:30+00:00 journal Devel::NYTProf <p>Another week another QA tool.</p><p>This week I&#39;m going to talk about <a href="">Devel::NYTProf</a> (aka NYTProf).</p><p>To start, if you&#39;re interested in profilers, you should check out the brief <a href="">history section</a> of the pod, then take a glance at its <a href="">features</a>. Until recently, I hadn&#39;t been very interested in profiling my code. I didn&#39;t really have anything that needed the profiling, and the tools just seemed a bit awkward to me. This changed for me when I saw the output from nytprofhtml (<a href="">1</a>, <a href="">2</a>).</p><p>While working on Image-TextMode, I noticed that parsing large (~75k) ANSI files was getting to be pretty slow. I decided to run NYTProf on the parsing code, and here&#39;s what I got:</p><p>[Image: <a href="">Profiling - Before</a>]</p><p>The putpixel(), width() and height() methods are called for every character/attribute combo stored for the image. This turns out to be a really big inefficiency. I&#39;ve had some XS code in my back pocket for ANSI parsing, so I decided to whip up a replacement parser using that code and run the profiler again.</p><p>[Image: <a href="">Profiling - After</a>]</p><p>Huge win! By moving _read() to XS (including putpixel, width, and height) I was able to shave over a second off of the total time (_read inclusive goes from 1.3 seconds to 0.03). Although working with XS was a bit of a pain, it was really great to see such a speed improvement.</p><p>I recommend everyone take a look at NYTProf if you&#39;re looking find speed inefficients in your code.</p> LTjake 2009-05-11T15:41:46+00:00 journal Perl::Critic <p>Holy -- this weekly thing goes by way too fast!</p><p>Anyway, as promised, I&#39;m making my first QA tool post. This week, we&#39;re chatting about <a href="">Perl::Critic</a>.</p><p>Perl::Critic has been around since late 2005. I was able to resist its icy gaze until last fall. So, why wouldn&#39;t I want to jump right in with Perl::Critic early on? Mostly what I imagined was putting a significant amount of time in to bend Perl::Critic policies to my will so I wouldn&#39;t have to change how I code. This is, of course, the wrong way to look at it.</p><p>There&#39;s nothing wrong with having a tool that confirms you&#39;re doing the right thing -- but what I really wanted was a tool that showed me the bad habits I&#39;ve learned and gave me a slap on the wrist every time I tried to use them. The easiest way to get started was to copy someone else&#39;s polcy file. RJBS was nice enough to comply.</p><p>For the Image::TextMode project, after adding my own tweaks to the policies, <a href="">this is the result</a>. A simple <a href="">automated test</a> integrates it into my development cycle.</p><p>After running it against my code, it found some issues -- most of my which were pretty tame: 2-arg open, lack of pod, plus a few regex and character matching niggles.</p><p>In my policy file, I have two sections: Things I don&#39;t agree with and things I&#39;ve had to disable temporarily. I hope to eventually go back and clean up my code so I can remove the remainder of the temporarily disabled policies. The policies I don&#39;t agree with may change over time, but this is my current list of preferences.</p><p>I have yet to use this setup in any other project, but I think the tool is useful enough that I could put it into place from the very beginning of a project or go back and run it against all of my old projects over time.</p><p>Until next time...</p> LTjake 2009-05-01T19:42:40+00:00 journal Projects Updates and QA Tools <p>NB: This is my first post in the <a href="">EPO Iron Man challenge</a>. (Warning: contains some expletives)</p><p>First and foremost, the long awaited <a href="">Catalyst 5.8</a> is out! My mind-share has primarily been with the 5.7x series so I&#39;ve been pretty much out of the loop on everything that&#39;s going on. Luckily enough, everything is basically backwards compatible (less any necessary module upgrades).</p><p>Besides the usual round of bug fixes, this release is built on top of <a href="">Moose</a>. I&#39;m a big fan of Moose and the ease with which it lets me code, so I&#39;m very excited to see this feature. Be sure to check the <a href="">Changelog</a> for all of the details.</p><p>As far as my personal projects go, I&#39;ve finally been able to deprecate two of my oldest modules (Image::ANSI and Image::XBin) with the latest release of <a href="">Image::TextMode</a>. This release now mirrors all features provided by the two before it (and then some). It can now write each format (not 100% complete, but release-worthy) -- I&#39;ve even included a little bit of naive RLE compression.</p><p>Personal projects let me explore some new/different technologies which may not fit in do my daily $work. One of those would be Moose, as mentioned above (which is now part of our standard &quot;toolkit&quot;). Another would be XS. Writing <a href="">Image::TextMode::Reader::ANSI::XS</a> was very eye opening as far as hooking Perl and C code together and illuminating the Perl internals for me.</p><p>Recently, I&#39;ve been in tune with adding new QA tools to my repertoire, such as: Benchmark (high time I learned more about it), Perl::Critic (again, about time) and Devel::NYTProf.</p><p>If I&#39;m going to keep up with this &quot;Iron Man Challenge,&quot; then maybe I will save my favorite QA tools for their own post. Stay tuned!</p> LTjake 2009-04-22T18:38:35+00:00 journal github <p>Like so many before me, I have now joined the github cabal.</p><p> <a href="">Check out my projects</a>.</p><p>One of the more interesting parts of github is their breakdown of <a href="">projects by language</a>. At the time of this post, Perl has 6% of the projects -- tied with C, 1% more than PHP, 3% less than Python and most surprisingly 1% less than &quot;Shell&quot;.</p><p>Obviously, given the origin of github, Ruby is way in the lead with 30%. But, I have a feeling that as people get more savvy about SCM tools, especially distributed SCM tools, Perl will make a significant dent in that.</p> LTjake 2009-03-24T14:50:48+00:00 journal Catalyst 5.71000 <p>Like i said back in <a href="">July</a>, Catalyst 5.71000 would happen before the moose-ified 5.80 gets shipped. That day is <a href="">here</a>. Here&#39;s the basics on what&#39;s new since 5.7015:</p><ul> <li>Relatively chained actions&#160;&#160;&#160; </li><li>PathPrefix (I only mentioned that, oh, <a href="">2 years ago</a><nobr> <wbr></nobr>:)&#160;&#160;&#160; </li><li>$c-&gt;go and $c-&gt;visit (they do a full dispatch to the action; this should kill the <a href="">SubRequest plugin</a>)&#160;&#160;&#160; </li><li>Refactored component resolution (which is something else <a href="">I worked on</a>)&#160;&#160;&#160; </li><li>Documentation improvements&#160;&#160;&#160; </li><li>Misc bug fixes</li></ul><p>There&#39;s a <a href="">full changelog</a> available. You might also browse the <a href=";to=Catalyst-Runtime-5.71000">search.cpan diff from 5.7015 to 5.7100</a>.</p><p>Enjoy! </p> LTjake 2009-01-19T21:06:51+00:00 journal Series of articles featuring WebService::Solr <p>I&#39;ve had a number of people show interest in <a href="">WebService::Solr</a> since its release last fall. This is really encouraging.</p><p>Especially encouraging is seeing <a href="">Eric Lease Morgan</a>&#39;s <a href="">first article in a series of three</a> dealing with indexing and searching using WebService::Solr. The initial post deals with some basic definitions, setting up Solr and writing a basic set of indexing and searching scripts.</p><p>It&#39;ll be great to see how the module gets used in a truly practical way. </p> LTjake 2009-01-08T20:57:12+00:00 journal Joining the Debian Perl group <p>At $work, we have a number of Ubuntu servers, and all of the developers use Ubuntu for their desktop OS. This has been the case since the 6.04 release of Ubuntu.</p><p>I&#39;m the first to admit that I&#39;m not much of a sysadmin. The general advice for installing modules, as I&#39;ve read, was to install the version from the apt repository when available. No problem there. Other than that, I&#39;ve always just used the cpan shell to install what I was missing. Apparently, over time, mixing the two methods tends to break down.</p><p>Last summer, i finally broke down and got familiar with <a href="">dh-make-perl</a>. It made creating<nobr> <wbr></nobr>.deb files for modules criminally easy. I also took this one step further and setup a <a href="">reprepro</a>-based deb repository on an internal server so all of our machines could benefit from the<nobr> <wbr></nobr>.deb files I had created.</p><p>In the spirit of giving back, I began to wonder how I could help out upstream by injecting some of these missing packages. It turns out that Ubuntu synchronizes its packages from the Debian unstable repository on occasion. So, how does one get things into the debian repository?</p><p>Enter the <a href="">Debian Perl group</a>.</p><p>To sum up their <a href="">announcement</a>, they basically handle all perl module related packaging tasks for Debian. After finding them on IRC and applying to the group I was quickly accepted and thrown into the fray.</p><p>I decided that it would be best to install Debian in a VM and do my packaging there instead of trying to hack around Ubuntu-specific issues. The <a href="">Debian Perl site</a> has a number of good guides to get you moving. I&#39;ll try to summarize the basics.</p><p>For new packages, one must first create an ITP or <a href="">Intent To Package report</a>. This comes across the line as a bug report filed against the &quot;wnpp&quot; pseudo-package. The reportbug tool makes this a trivial task.</p><p>The group uses an svn repository to keep track of all of their work, so the next step is to <a href="">inject your initial work</a> into that repository. svn-inject will take care of this for you, as long as you have the<nobr> <wbr></nobr>.orig.tar.gz,<nobr> <wbr></nobr>.diff and<nobr> <wbr></nobr>.dsc files. To get those files, I did the following:</p><ul> <li>use dh-make-perl to intialize the package: dh-make-perl --cpan Foo-Bar --pkg-perl&#160; </li><li>cd Foo-Bar&#160;&#160;&#160; </li><li>use debuild -S to create the source package&#160;&#160;&#160; </li><li>finalize the process with the svn-inject helper</li></ul><p>Once you&#39;ve injected the new module, you&#39;ll need to massage all of the debian/* files to get them up to spec -- in which there are many nuances that I&#39;m still trying to figure out. The folks on the IRC channel are very knowledgeable and have helped me numerous times there.</p><p>If you think your package is ready to go into the repository you can change the release status from UNRELEASED to unstable (&quot;dch -r&quot; helps here) and someone will review it. Hanging out in the IRC channel can speed things along. If all is well, they will take care of the rest from there.</p><p>To <a href="">update an existing package</a>:</p><ul> <li>check out the existing package from svn&#160;&#160;&#160; </li><li>use uscan to get the new tarball&#160;&#160;&#160; </li><li>use svn-upgrade to inject the new data into the repository</li></ul><p> Again you have to massage the debian/ files based on the new tarball data and the same review process applies.</p><p>As things are uploaded, you&#39;ll get a fancy developer page, <a href="">like this</a>. Also, the Debian Perl group has a really great <a href="">status page for the repository</a> that can tell you when new upstream packages are available, or what&#39;s been worked on in the repository.</p><p>The aforementioned <a href="">dh-make-perl helper</a>, which is also under maintenance of the Debian Perl team, is undergoing some major refactoring. It is being re-worked in a more modular form down from it&#39;s monolithic 2000-line single-file status. At the same time, a test suite is being added so no further regressions will occur. I&#39;ve tried to help out where I can, but this a huge task with many opportunities to screw things up, so the more eyes on the code, the better!</p> LTjake 2009-01-07T19:55:06+00:00 journal Solr Power! <p>I am reminded of the crowds at Canadian national <a href="">curling</a> events. There&#39;s always at least one really loud person in the upper seats that yells out &quot;POLAR POWER!&quot; then pulls a string through a coffee can to imitate the sound of a moose.</p><p>I kid you not. God bless this country.</p><p>Anyway.</p><p>For our latest project at $work, we decided to use <a href="">Solr</a> for indexing and searching. There is a <a href=""></a> on, but I wasn&#39;t overly thrilled with the overall design.</p><p>So, in TIMTOWTDI style, I&#39;ve created <a href="">WebService::Solr</a>. As added bonuses, I&#39;ve created a <a href="">model for Catalyst</a> and a <a href="">hook into DBIx::Class::Indexed</a>.</p><p>I&#39;m not 100% sold on the way I have things designed, but I&#39;ve had some people show some interest in the module, so I hope to get some feedback soon.</p> LTjake 2008-10-28T01:35:48+00:00 journal Retro to the max ... times 2! <p>Recently, two CPAN releases have brought a certain amount of nostalgia to my mind&#39;s eye.</p><p>Andy Armstrong contacted me a number of months ago in relation to my <a href="">6502 CPU</a> work.&#160; Mostly he was disappointed in the lack of a test suite. I felt much the same way, and had really wanted a test suite for the next release. After numerous hours of searching, I stumbled upon the <a href="">MoneyNES project</a>.</p><p>That particular project has a set of scripts to test all (well, not quite all) of the ops and basic memory functions available to 6502 processors. I was able to write a <a href="">simple parser</a> to bind Acme::6502 to the test scripts and I instantaneously had a good number of tests for Andy&#39;s code.</p><p>To this end, for the <a href="">latest release of Acme::6502</a> I was able to fix a few bugs including:</p><ul> <li>Fix PLP to clear B flag instead of setting it</li><li>Fix TSX to set N and Z flag based on the value of X</li><li>Emulate a page boundary bug in JMP instructions</li><li>Fix BRK to set B flag</li></ul><p>Unfortunately, I was also able to find a few issues with the test suite. These were sometimes hard to spot but Andy is very knowledgeable and I was also able to find a really cool <a href="">javascript-based 6502 emulator</a> which confirmed our suspicions. I&#39;ve sent patches to the suite upstream, and the author was very responsive -- though he says the project is dormant for now.</p><p>So, apparently Schwern owes me some Euros*<nobr> <wbr></nobr>;)</p><p>The other bit of nostalgia deals with BBS-era art. I have a couple text mode art modules (<a href="">1</a>, <a href="">2</a>) on CPAN already. In reality there are at least 5 variations on the standard &quot;ansi art&quot; format. I&#39;ve compiled a fairly detailed set of modules to handle these formats and uploaded it to CPAN in the form of <a href="">Image-TextMode</a>.</p><p>I&#39;ve uploaded some <a href="">sample renderings</a> so you can see the variety of formats and options available. Among those options we have:</p><ul> <li>&quot;9th bit&quot; -- the standard font is 8 bits wide, but typical displays used 9 bits (8th bit repeated).</li><li>&quot;iCEColor&quot; -- basically non-blink mode, last bit of the attribute byte now becomes part of the background color data</li><li>&quot;ced&quot; -- black-on-gray</li></ul><p>The formats vary on 3 different aspects:</p><ol> <li>Font -- Sometimes it just an 8x8 font instead of 8x16. Sometimes it&#39;s the &quot;Amiga&quot; font. Other times it&#39;s a completely custom font so artists can have free reign over the blocks</li><li>Palette -- Allowing different colors allowed for a more truer representation for meat-space-based drawings (hello skin tones!), but I always found that the palette limitation forced artists to be truly creative. Anyway, the Tundra format actually allows for any number of colors on a 24bit spectrum.</li><li>Dimensions -- why be stuck with 80 columns, when you could do 160? or 234? or some other random number?</li></ol><p>The sad truth is that by the time most of these advances came along the &quot;scene&quot; was already on its way out, and judging but their usage, people really only believed there was &quot;one true format&quot;&#160; -- the standard 8x16 font on a 16-color, 80 cols display.</p><p>This was one of my first experiments with <a href="">Moose</a> -- which ended up being quite enlightening. I still have some room to grow as far as using Moose to its full potential, but I&#39;m definitely sold.</p><p>* Andy tells me he won an auction wherein Schwern was to add a test suite to Acme-6502<nobr> <wbr></nobr>:)</p> LTjake 2008-10-16T02:08:06+00:00 journal Accouncing: <p>For those of you who don&#39;t know, I live in Eastern Canada. Fredericton, specifically -- the capital of the province of New Brunswick. It&#39;s a pretty small place, especially as far as capital cities go. I believe we&#39;re only the 3rd largest city in the province.</p><p>With such a small place, user groups seem to be hit and miss. We used to have a Linux user group: FLUX (Fredericton Linux User eXchange -- cute, eh?<nobr> <wbr></nobr>:), then there was Linux Fredericton (still active, perhaps?). Most recently has been an Ubuntu specific group -- I might actually go to one of their meetings, should they schedule any more.</p><p>I&#39;ve searched over the last few years for some sort of &quot;scripting&quot; group in town, but have come up with nada. So, last week I finally bit the bullet and opened my own Perl Mongers branch -- <a href=""></a>!</p><p>At this point, the group is basically a name and that&#39;s all. However, I hope to use that name to improve the visibility of Perl in Fredericton, and the surrounding Atlantic region. Perhaps, if i can get the word out to enough people, I might find a group of folks interested in not just Perl, but languages in the same range (PHP, Python, Ruby, etc) and we can get together and share our thoughts and ideas.</p><p>Wish me luck.</p> LTjake 2008-07-28T02:02:47+00:00 journal Component resolution in Catalyst 5.7100 <p>One of the things you&#39;ll see in the changelog for the next stable release of Catalyst, is a reworked component resolution system. By &quot;component resolution&quot; i mean, fetching components from view()/views(), model()/models(), controller()/controllers() and component().</p><p>Back in May I posted <a href="">a message to the Catalyst-dev list</a> describing some issues with the way it was currently working. Although I painted a slightly convoluted picture of doom and gloom -- it turns out that all is not lost; you were probably relying on an &quot;undefined&quot; behavior to begin with (kind of like assuming &quot;keys %hash&quot; will return things in a particular order).</p><p>For example, consider &quot;MyApp&quot; with two views: &quot;Foo&quot; and &quot;Bar.&quot; Now, when you call &quot;$c-&gt;view()&quot; (i.e. with no arguments) what gets returned? Well, it depends.<nobr> <wbr></nobr>:) If you have none of the appropriate config (default_view) or stash variables (current_view, current_view_instance) set, then it&#39;s pretty much random.</p><p>If you write a test for the above, and see that &quot;MyApp::View::Bar&quot; is returned -- don&#39;t count on that test working in 5.7100 (the message I posted to the list has the technical details as to why). Though the test *may* continue to work, the above scenario will throw a pretty large warning:</p><blockquote><div><p>Calling $c-&gt;view() will return a random view unless you specify one of:<br>* $c-&gt;config-&gt;{default_view} # the name of the default view to use<br>* $c-&gt;stash-&gt;{current_view} # the name of the view to use for this request<br>* $c-&gt;stash-&gt;{current_view_instance} # the instance of the view to use for this request<br>NB: in version 5.80, the &quot;random&quot; behavior will not work at all.</p></div> </blockquote><p>(FYI, if your application only has one view, calling &quot;$c-&gt;view()&quot; is considered &quot;acceptable&quot; and will spare you the warnings.)</p><p>A similar warning is thrown for $c-&gt;model(). $c-&gt;controller() with no arguments will continue to return the controller for the dispatched action. $c-&gt;component (sans args) will also stay the same, returning a sorted list of all component names.</p><p>Another issue I discovered while re-working the code was a failed reliance on the &quot;regex&quot; fallback.</p><p>Consider another &quot;MyApp&quot; with two views &quot;Foo::Bar&quot; and &quot;Foo::Baz&quot;. What does &quot;$c-&gt;view(&#39;Foo&#39;)&quot; return? We&#39;ve maintained backwards compatibility on this one -- it will return all matching views (order unknown). It is important to note that this returns an array, so list context is important. We&#39;ve added a warning for this scenario as well:</p><blockquote><div><p>Relying on the regexp fallback behavior for component resolution is unreliable and unsafe.<br>If you really want to search, pass in a regexp as the argument.</p></div> </blockquote><p>As noted above, if you truly were just searching for views, pass it a regex (&quot;$c-&gt;view(qr{Foo})&quot;) and it will act as expected.</p><p>So, if you think you might be affected by these particular issues, <a href="">test out the dev release</a>! Don&#39;t say I didn&#39;t warn you.<nobr> <wbr></nobr>:)</p> LTjake 2008-07-17T13:55:34+00:00 journal Please test Catalyst::Runtime 5.7100 RC1 (aka 5.7099_02) <p>(Crossposted to the Catalyst-dev list)</p><p>We&#39;re putting out one final development release before we go full bore<br>with 5.7100.</p><p>NB: It is IMPERATIVE that you TEST this release against YOUR code. Quoth<br>mst: &quot;If you do not test now any bugs we ship with are your fault!&quot; --<br>so, there you have it<nobr> <wbr></nobr>:)</p><p>Also, we&#39;ve reworked the authors list to be much like DBIx::Class; in<br>one spot ( with each person&#39;s IRC nick, name, and email. In<br>you can fill in any of the blanks, fire off an email or catch us in<br>#catalyst-dev and well gladly fix it up.</p><p>Whilst the release is making its way to CPAN, you can grab it from here:</p><p> <a href=""></a> </p><p>The Changes since the last stable release include:</p><p>5.7099_02 2008-07-16 19:10:00<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; - Added PathPrefix attribute<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; - Removed Catalyst::Build; we&#39;ve long since moved to<br>Module::Install<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; - Updated Catalyst::Test docs to mention the use of HTTP::Request<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; objects (Rafael Kitover)</p><p>5.7099_01 2008-06-25 22:36:00<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; - Refactored component resolution (component(), models(),<br>model(), et al). We now<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; throw warnings for two reasons:<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 1) model() or view() was called with no arguments, and two<br>results are returned<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; -- set default_(model|view), current_(model|view) or<br>current_(model|view)_instance<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; instead<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2) you call a component resolution method with a string, and<br>it resorts to a regexp<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; fallback wherein a result is returned -- if you really<br>want to search, call the<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; method with a regex as the argument<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; - remove 0-length query string components so warnings aren&#39;t<br>thrown (RT #36428)<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; - Update HTTP::Body dep so that the uploadtmp config value will<br>work (RT #22540)<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; - Fix for LocalRegex when used in the Root controller<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; - Get some of the optional_* tests working from dirs with<br>spaces (RT #26455)<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; - Fix Catalyst::Utils::home() when application<nobr> <wbr></nobr>.pm is in the<br>current dir (RT #34437)<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; - Added the ability to remove parameters in req-&gt;uri_with() by<br>passing in<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; an undef value (RT #34782)<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160; - Added $c-&gt;go, to do an internal redispatch to another action,<br>while retaining the<br>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; contents of the stash</p> LTjake 2008-07-16T22:16:59+00:00 journal Catalyst 5.71 is nigh <p>We&#39;re approaching the two-year anniversary of the <a href="">first release</a> in the 5.7x series of the Catalyst framework. I&#39;m really proud of how 5.7x has gone -- it has given the project some much needed stability that was missing in the early goings. It still amuses me to look back at the changelog to watch it go from version 3.X (which is basically &quot;Catalyst 1.0&quot;) to 5.X in the span of about two and a half months.</p><p>Although development was obviously very fast-paced then, with 14 releases since 5.7000 I wouldn&#39;t say we&#39;ve stalled. Naturally, the bulk of the changes since then have been bug fixes. We&#39;ve also increased the test suite from 1416 tests to 1805 (the old test suite actually ran most tests twice by default, but, by setting CAT_BENCH_ITERS=1, you will see the &quot;1416&quot; result).</p><p>A 5.71 dev release (<a href="">5.7099_01</a>) was recently shipped which includes a new method: go(). As marcus describes it, it &quot;works like an internal redispatch to another action, while retaining the stash intact.&quot; I believe one more dev release will happen as I&#39;ve recently checked in the long lost <a href="">PathPrefix attribute</a>.</p><p>5.71xx will be more of a short-lived series of releases to act as a buffer between 5.70XX and 5.8000. 5.8000 being the <a href="">Moose</a> conversion (see <a href="">this interview</a> for more information). </p> LTjake 2008-06-27T16:12:11+00:00 journal 5 more down <p>Catalyst 5.7014 is out the door. Hopefully that will stop the flood of questions about a &quot;strange uri_for() behavior.&quot; With that done, I&#39;ve taken out 5 more RT tickets.</p><p>Two extremely old wishlist items were rejected (<a href="">RT #26758</a>, <a href="">RT #24132</a>). This is basically due to the fact that they were over a year old, and really should be talked about on the dev list if they are still inclined to have them resolved.</p><p>A couple others required that I cook up a test or two to ensure the patch was applying was satisfactory (naturally, we would always hope to have a test submitted along side the patch): <a href="">RT #26455</a>, <a href="">RT #34437</a>.</p><p>The last ticket seems to have been related to a regression in 5.7013, as the ticket author claims the latest release fixed the issue. Closed! (<a href="">RT #35994</a>)</p> LTjake 2008-05-27T11:36:30+00:00 journal More Catalyst fixes <p>I&#39;ve put the 5-a-day thing away for a bit to focus on other things. Firstly it was trying to get a new release of Catalyst-Runtime out the door (5.7013 hit CPAN on the 17th). One of the last bits preventing that release was some back-compat methods for Catalyst::Stats so it could mimic Tree::Simple behavior, which is what $c-&gt;stats() used to return.</p><p>Unfortunately, this release introduced two regressions, now fixed in svn:</p><p>1) &quot;sub foo : Path {}&quot; in the root controller didn&#39;t work.</p><p>This was as a result of my attempt to allow Path(0) to match properly. A simple 1-line fix resolved this problem. This bug also prevents some components&#39; tests from working successfully (so far Catalyst-Model-Adaptor and Catalyst-Plugin-Unicode) as they used this idiom in their test apps.</p><p>2) invalid namespace for relative arguments to uri_for from an action that was run from a $c-&gt;forward() command.</p><p>Since there are a few conditions to satisfy before this bug appears I&#39;m not too suprised it snuck in to the release. Peter Karman provided a much needed test case and the simple fix (remove &quot;local $c-&gt;{namespace} = $self-&gt;namespace&quot;) which i&#39;ve included in the 5.70 trunk.</p><p>I hope we can get 5.7014 out the door relatively swiftly.</p><p>I&#39;ve also fixed up a couple of Catalyst::Plugin::Authentication RT tickets. Both were simple pod fixes: <a href="">RT #36062</a>, <a href="">RT #36063</a></p> LTjake 2008-05-23T19:15:02+00:00 journal Five a day, May 10 <p>My latest five:</p><p> <a href="">RT #33158</a> - rejected (DBIx::Class)<br> <a href="">RT #25445</a> - already applied (DBIx::Class)<br> <a href="">RT #26978</a> - closed (DBIx::Class)<br> <a href="">RT #31473</a> - closed (DBIx::Class::Schema::Loader)<br> <a href="">RT #29041</a> - fixed this last year (Catalyst::Plugin::Session::PerUser)</p> LTjake 2008-05-10T14:34:07+00:00 journal Five a day, part 3 <p>I ventured into some DBIC related bugs this time.</p><p> <a href="">RT #32497</a> - rejected (Catalyst::Model::DBIC::Schema)<br> <a href="">RT #31848</a> - doc fixed (Catalyst::Model::DBIC::Schema)<br> <a href="">RT #29282</a> - duplicate (DBIx::Class::Schema::Loader)<br> <a href="">RT #23749</a> - already patched this last year (Catalyst::Plugin::Session::State::URI)<br> <a href="">RT #20142</a> - closed (Catalyst::Plugin::UploadProgress)<br> <a href="">RT #32276</a> - rejected (Catalyst::Runtime)<br> <a href="">RT #26732</a> - closed (Catalyst::Runtime)<br> <a href="">RT #34293</a> - duplicate (DBIx::Class)<br> <a href="">RT #32988</a> - pod fixed (DBIx::Class)<br> <a href="">RT #33217</a> - closed (DBIx::Class)</p> LTjake 2008-05-09T14:58:41+00:00 journal (Five a day) x 2 <p>I ended up doing twice my quota for today (it&#39;s easy to take care of the low-hanging fruit). A variety of Catalyst::* and DBIx::Class tickets were closed.</p><p> <a href="">RT #15941</a> - rejected (Catalyst::View::TT)<br> <a href="">RT #32254</a> - duplicate (Catalyst::Plugin::Authentication)<br> <a href="">RT #30506</a> - closed (Catalyst::Plugin::Authentication)<br> <a href="">RT #33302</a> - closed (Catalyst::Manual)<br> <a href="">RT #32091</a> - closed (Catalyst::Manual)<br> <a href="">RT #29496</a> - duplicate (Catalyst::Manual)<br> <a href="">RT #32636</a> - pod fixed (Catalyst::Manual)<br> <a href="">RT #34256</a> - dependencies updated (DBIx::Class)<br> <a href="">RT #33667</a> - patch applied (Catalyst::Session::Store::FastMmap)<br> <a href="">RT #32393</a> - closed (DBIx::Class)</p> LTjake 2008-05-08T21:21:09+00:00 journal Five a day, plus two. <p>The Ubuntu&#160;<a href="">&quot;5-A-Day&quot;</a> campaign has caught my eye. It&#39;s turned a heinous task into a bit of a game. It reminds me a little bit of the <a href="">ESP Game</a> for image tagging (i.e. boring task =&gt; game).</p><p>I don&#39;t expect I could ever really take care of 5 bugs every single day, but I&#39;ve given myself a little jump start by closing 7 Catalyst-related bugs yesterday. Only one of them took a significant amount of time to fix as it required some patching to the various parts of the Catalyst dispatch cycle.</p><p>Here are my five (plus two):</p><p> <a href="">RT #30660</a> - Just needed to be closed<br> <a href="">RT #30087</a>&#160;- Again, just needed to be closed<br> <a href="">RT #35690</a> - Fixed POD<br> <a href="">RT #33236</a> - Tiny grammar fix<br> <a href="">RT #29334</a> - Fixed in trunk<br> <a href="">RT #26452</a> - Test workaround in trunk<br> <a href="">RT #24743</a> - Latest Catalyst::Manual upload fixes this</p> LTjake 2008-05-08T12:17:35+00:00 journal Quick! grab two of *everything* <p> So, we&#39;re experiencing the worst flooding we&#39;ve ever had in 35 years. <a href="">[1]</a> <a href="">[2]</a> My $work is only a few blocks from the river, but we&#39;ve lucked out and haven&#39;t had any water in the building. What&#39;s even more remarkable is that they didn&#39;t shut the power off to our section of the grid so all of our services remain online! (disaster planning?&#160;ppfft! who needs it?)</p><p>The office was closed Thursday as the city wanted people to stay out of the downtown district. We came down anyway (as did a pile of other people) to try and grab some photos.</p><p> <i> <a href="">To view the photos, please check out my blog on vox.</a> </i> </p> LTjake 2008-05-02T12:28:40+00:00 journal Import Amarok stats into Rhythmbox <p>I&#39;ve been using Ubuntu since Dapper was released. As Hardy is the next LTS release, I decided now would be a good time to blow the whole thing away and start fresh. At the same time, I thought I could give rid of some KDE-based software I&#39;ve been using and stick to a strictly Gnome environment.</p><p>I&#39;ve been using Amarok as my media player, but, as stated above, that doesn&#39;t jive with a pure Gnome setup. By default Rhythmbox is installed. I can import all of my tunes in no problem, but I&#39;m missing some play stats.</p><p>Given my old Amarok database, which is just an SQLite database, and a Rhythmbox database, which is a simple XML file, with freshly imported tunes I was able to write a script to pull out some of my old data including: rating, import date, last play date and play count. NB: Rhythmbox ratings don&#39;t understand half-star ratings, though it doesn&#39;t complain.</p><p>Usage: rhythmdb.xml collection.db</p><p>use strict;<br>use warnings;</p><p>use XML::Simple;<br>use DBI;<br>use URI;</p><p>my $xml = shift;<br>my $data = XMLin( $xml, KeepRoot =&gt; 1, ForceContent =&gt; 1 );</p><p>my $dbh = DBI-&gt;connect( &#39;dbi:SQLite:dbname=&#39; . shift, undef, undef );<br>my $sth = $dbh-&gt;prepare( &#39;select rating, playcounter, createdate, accessdate from statistics where url = ?;&#39; );</p><p>for my $row ( @{ $data-&gt;{ rhythmdb }-&gt;{ entry } } ) {<br>&#160;&#160;&#160; my $mp3 = URI-&gt;new( $row-&gt;{ location }-&gt;{ content } );</p><p>&#160;&#160;&#160; next unless $mp3-&gt;scheme eq &#39;file&#39;;</p><p>&#160;&#160;&#160; $sth-&gt;execute( &#39;.&#39; . $mp3-&gt;file );</p><p>&#160;&#160;&#160; my $dbrow = $sth-&gt;fetchrow_hashref;<br>&#160;&#160;&#160; $row-&gt;{ rating }-&gt;{ content } = $dbrow-&gt;{ rating } / 2;<br>&#160;&#160;&#160; $row-&gt;{ &#39;play-count&#39;}-&gt;{ content } =&#160; ( $row-&gt;{ &#39;play-count&#39;}-&gt;{ content } || 0 ) + $dbrow-&gt;{ &#39;playcounter&#39; };<br>&#160;&#160;&#160; $row-&gt;{ &#39;first-seen&#39; }-&gt;{ content } = $dbrow-&gt;{ &#39;createdate&#39; };<br>&#160;&#160;&#160; $row-&gt;{ &#39;last-seen&#39; }-&gt;{ content } = $dbrow-&gt;{ &#39;accessdate&#39; };<br>}</p><p>XMLout( $data, KeepRoot =&gt; 1, XMLDecl =&gt; 1, OutputFile =&gt; $xml );</p> LTjake 2008-04-26T02:00:28+00:00 journal non-blocking USB access <p>Dear lazy-perl-web,</p><p>Has anyone done non-blocking access to USB devices? <a href="">Device::USB</a> uses <a href="">libusb</a> 0.1.x -- which only does blocking access. <a href="">libusb 1.0</a> is to include callback-based access -- it&#39;s under development at least, but no perl bindings exist.</p><p>Is there anything else out there to try?</p> LTjake 2008-04-09T14:48:50+00:00 journal