xsawyerx's Journal http://use.perl.org/~xsawyerx/journal/ xsawyerx'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:37:22+00:00 pudge pudge@perl.org Technology hourly 1 1970-01-01T00:00+00:00 xsawyerx's Journal http://use.perl.org/images/topics/useperl.gif http://use.perl.org/~xsawyerx/journal/ Two Perl Mongers meetings, three talks, two reviews http://use.perl.org/~xsawyerx/journal/40249?from=rss <a href="http://blogs.perl.org/users/sawyer_x/2010/03/two-perl-mongers-meetings-three-talks-two-reviews.html">Two Perl Mongers meetings, three talks, two reviews</a> xsawyerx 2010-03-17T10:54:09+00:00 journal Modules vs. Applications http://use.perl.org/~xsawyerx/journal/40245?from=rss <a href="http://blogs.perl.org/users/sawyer_x/2010/03/modules-vs-applications.html">Modules vs. Applications</a> xsawyerx 2010-03-15T07:40:52+00:00 journal Speeding Up Code http://use.perl.org/~xsawyerx/journal/40235?from=rss <a href="http://blogs.perl.org/users/sawyer_x/2010/03/speeding-up-code.html">Speeding Up Code</a> xsawyerx 2010-03-10T11:44:39+00:00 journal Dancer 1.160 is out! http://use.perl.org/~xsawyerx/journal/40231?from=rss <a href="http://blogs.perl.org/users/sawyer_x/2010/03/dancer-1160.html">Dancer 1.160 is out!</a> xsawyerx 2010-03-08T09:52:12+00:00 journal Search::GIN 0.04 finally out! http://use.perl.org/~xsawyerx/journal/40223?from=rss <a href="http://blogs.perl.org/users/sawyer_x/2010/03/searchgin-004-finally-out.html">Search::GIN 0.04 finally out!</a> xsawyerx 2010-03-04T16:26:49+00:00 journal Gaming FAIL http://use.perl.org/~xsawyerx/journal/40215?from=rss <p> <i>original post can be found on my <a href="http://blogs.perl.org/users/sawyer_x/">blog</a>.</i> </p><p>Many years ago, when I was... roughly 15 (I think), I met Theodor Ts'o (one of the first hardcore Linux Kernel hackers, since version 0.90, I believe) at a Linux event IBM organized in Israel. I should note that he is a very nice person.</p><p>After the event, we got to talk a bit. We talked about our favorite games. Mine was "avoiding segfaults". This was back when I was programming in C.</p><p>Today I wrote the following regex: <em>qr/^([\w|\.]+)\s+(?(\d+)\s+)?(\w+)\s+(?:(\d+)\s+)?([\w|\d|\.]+)$/;</em> </p><p>Then got a <em>Segmentation fault</em> </p><p>Can you spot the error?</p><p>Here's a hint: it is missing a colon (<strong>:</strong>).</p><p> <em>This is perl, v5.10.0 built for i486-linux-gnu-thread-multi</em> </p> xsawyerx 2010-03-01T13:20:41+00:00 journal Writing your own Search::GIN extractor http://use.perl.org/~xsawyerx/journal/40207?from=rss <p> <i>original post can be found on my <a href="http://blogs.perl.org/users/sawyer_x/">blog</a>. <b>note:</b> It has code embedded so it's easier to view it there.</i> </p><p>I stumbled into a tricky situation with <a href="http://search.cpan.org/perldoc?Search::GIN">Search::GIN</a> that required me to have a reverse indexing with set introspection. This situation isn't so rare, so I thought it would be helpful to share how I did it.</p><p>Suppose I have an object. The object has an attribute. The attribute is a set of objects. I need to be able to fetch the objects according to the value of an attribute of the objects in the set in the attribute of the original object. Err.. ya know what? Here's an example!</p><p>I have a few music preferences (blues, jazz, etc.), a few simpsons characters (Lisa, Homer, Barney). Each of them likes certain types of music. Lisa likes blues and jazz, while Barney only likes blues and Homer just likes stupid commercial jingles.</p><p>First define the objects:<br> <a href="http://gist.github.com/313365#file_gistfile1.pl">See here</a> </p><p>The create them:<br> <a href="http://gist.github.com/313365#file_gistfile3.pl">See here</a> </p><p>I want to be able to fetch all the people who like a certain type of music. This is a bit difficult since a person likes a <em>set</em> of music styles. Search::GIN::Extract::Attributes doesn't cover sets (though it would be cool if it could in the future) and I obviously don't want to go over all characters and do it.</p><p>Instead I wrote an extractor that does that:<br> <a href="http://gist.github.com/313365#file_gistfile2.pl">See here</a> </p><p>In order to use this extractor, in my DB interface (which <code>extends</code> <a href="http://search.cpan.org/perldoc?KiokuX::Model">KiokuX::Model</a>) I do this:<br> <a href="http://gist.github.com/313365#file_gistfile4.pl">See here</a> </p><p>And viola!</p><p>Now using Search::GIN::Query::Manual, I can search for any Character that likes Blues music:<br> <a href="http://gist.github.com/313365#file_query.pl">See here</a> </p><p> <i> I wanted to write all the code in this post but for some reason I can't put more than a few lines of code here and it always double spaces it. How do others put code here? </i></p> xsawyerx 2010-02-24T12:40:19+00:00 journal My first bug report! http://use.perl.org/~xsawyerx/journal/40203?from=rss <p> <i>original post can be found on my <a href="http://blogs.perl.org/users/sawyer_x/">blog</a>.</i> </p><p>Even though I helped on various projects, I never really got a bug report on a project of my own. I've gotten offline requests (usually from people who know me personally), but never an actual RT ticket.</p><p>Today I got my first RT ticket (in the mail) and I've very proud of it!</p><p>Apparently there was a change in <a href="http://search.cpan.org/perldoc?Template::Tiny">Template::Tiny</a>'s API. <em>mst</em> made it more compatible with <a href="http://search.cpan.org/perldoc?Template">Template::Toolkit</a> and <em>Adam Kennedy</em> released Template::Tiny 0.11 and took the time to open a ticket with <a href="http://search.cpan.org/perldoc?Dancer::Template::Tiny">Dancer::Template::Tiny</a> to require 0.11 and up, and update the code. I've updated the code, changed the requirement and done the same with <a href="http://search.cpan.org/perldoc?Task::Dancer">Task::Dancer</a>. Both of them on the way to CPAN as we speak.</p><p>Why am I sharing this small tidbit? (isn't tidbit a funny word? I think it is)</p><p>Because I was really excited about it. The way people take a global look on things in CPAN. Updating each other's code, tickets and patches, notifying each other of API changes that might relate, etc. In Hebrew we have two phrases that relate to this: a "big head" and a "small head". A "big head" (<em>rosh gadol</em>) is someone who looks at the bigger picture. A "small head" (<em>rosh katan</em>) is someone that tries to know the least s/he can. Even though trying to concentrate on something specific isn't bad, the terms try to relate to laziness and caring, which gives them connotations of good and bad. In English, though, it sounds like I'm vaguely cursing someone.</p><p>I really do hope I'll keep feeling good about incoming tickets.<nobr> <wbr></nobr>:)</p> xsawyerx 2010-02-22T18:11:11+00:00 journal Dancer gets Route Caching http://use.perl.org/~xsawyerx/journal/40202?from=rss <p> <i>original post can be found on my <a href="http://blogs.perl.org/users/sawyer_x/">blog</a>.</i> </p><p>Recently I've spent more time with <a href="http://dancer.sukria.net/">Dancer</a> development, since it's such a fast, fun and flowing project. I've written <a href="http://search.cpan.org/perldoc?Task::Dancer">Task::Dancer</a> (after bugging a few people on #toolchain - thanks <em>daxim</em>!), <a href="http://search.cpan.org/perldoc?Dancer::Template::Tiny">Dancer::Template::Tiny</a> and even patched <a href="http://search.cpan.org/perldoc?Dancer::Template::Tenjin">Dancer::Template::Tenjin</a> (and thanks to <a href="http://ido50.net/"> <em>Ido</em> </a> for released it so quickly!).</p><p>Once thing I recently implemented in Dancer is Route Caching. Route Caching is a new term - at least for me - since I don't remember seeing it elsewhere (though I wouldn't be surprised if it's implemented in other frameworks).</p><p>When Dancer gets all the routes you want, it compiles them into regular expressions in a registry and then matches each request against the compiled routes, returning the first match. Route Caching allows to cache the path matches.</p><p>Theoretically if you have about 40 routes, and your 10 most wanted requests are in the lower set of the registry, Dancer would still have to go over the registry top to bottom, trying to match your request to a given compiled route. This is standard procedure and makes sense in every framework. However, this could be sped up.</p><p>Route Caching caches which request went to which compiled route and returns the compiled route instead of letting it go through the registry. As if it is saying "oh, this request? I know it, it goes to this specific route, no need to check the entire registry.</p><p>This, however, could be a sensitive issue, since many variable-based paths (/get/artist/:id) can increase the cache, taking more and more. You could set a size limit or a path limit, limiting either the size of the cache (KB, MB, GB) or the amount of paths it caches.</p><p>Once I add a feature to use the disk to read and write the cache, it would enable CGI-based applications to reap the benefits as well, without having persistence.</p><p>At first I thought this was pretty cool but as the evening set I was quite discouraged thinking maybe I should have worked on actually caching the results of pages (which Dancer will have soon enough). Today Alexis showed me results of benchmarks he did.</p><p>The benchmark test is available <a href="http://gist.github.com/310992">here</a>, and these are the results he had:<br> <em>&lt;sukria&gt; without caching: Requests per second: 73.19 [#/sec] (mean)<br> &lt;sukria&gt; with caching: Requests per second: 225.66 [#/sec] (mean)<br> &lt;sukria&gt; SCORE!<br> &lt;sukria&gt;<nobr> <wbr></nobr>;)<br> &lt;sawyer&gt; oooo</em> </p><p>This is not bad considering the caching isn't even on results, only on the matching of routes. Not too shabby.<nobr> <wbr></nobr>:)</p> xsawyerx 2010-02-22T18:09:58+00:00 journal Midway Culmination http://use.perl.org/~xsawyerx/journal/40192?from=rss <p> <i>original post can be found on my <a href="http://blogs.perl.org/users/sawyer_x/">blog</a>.</i> </p><p>Recently I started a new project at $work in which I'm using a lot of cool projects (<a href="http://search.cpan.org/perldoc?DBIx::Class">DBIx::Class</a>, <a href="http://www.iinteractive.com/kiokudb/">KiokuDB</a>, <a href="http://search.cpan.org/perldoc?Search::GIN">Search::GIN</a>, <a href="http://search.cpan.org/perldoc?POE">POE</a> and <a href="http://dancer.sukria.net/">Dancer</a> to name a few) and it involved a lot of layers so I wanted to do this one <em>just right</em>.</p><p>I finally started using KiokuDB and it went relatively easy, though Search::GIN is still lacking (and 0.4 still hasn't been released to CPAN, so I'm relying on the code on Github). It's amazing how easily I can write tests with KiokuDB and plug my stuff in and out. Sometimes, I have a hard time realizing it's that simple.</p><p>I finally started using DBIx::Class <em>correctly</em>. Up until now, I just used it to hook up to SQLite/MySQL database tables I've previously created. Now I actually use <em>deploy()</em>. I've also created a full schema detail, which is something I hardly ever do. When I just started using DBIx::Class, I had a hard time going over the docs. I asked for help more than once. However, this time the documentation was a breeze, fun to read, easy to understand and I only spent a few minutes doing <strong>everything</strong> I needed. Either the docs are much better, or I'm smarter. Either way, WIN!<nobr> <wbr></nobr>:)</p><p>Dancer is improving rapidly. I'll be releasing <a href="http://search.cpan.org/perldoc?Dancer::Template::Tiny">Dancer::Template::Tiny</a> soon enough, and the core is pushing more changes every day, thanks to <a href="http://blogs.perl.org/users/david_precious/2010/02/dancer-web-framework-1150-released.html">hard-working co-developers</a> and a steady hand at the wheel.</p><p>Last two days, however, I spent on a bug in <a href="http://search.cpan.org/perldoc?POE::Component::Generic">POE::Component::Generic</a>. Apparently, when wrapping <a href="http://search.cpan.org/perldoc?Net::OpenSSH">Net::OpenSSH</a>, some methods lead to an infinite hang. Net::OpenSSH does a lot of stream magic with stdin/stdout/stderr, and might be causing this, but I'm not sure. It could also be a reference leak. Using the <em>async</em> mode directly with POE::Kernel works, but gives a "connection closed" message. I've opened ticket #54744.</p><p>Yesterday I've had Nicholas Perez and Rocco Caputo help me with debugging this. I'd like extend my gratitude, this isn't the first (or even second) occasion they've helped me with POE-related problems and they put time and effort into explaining things or helping with stuff, which I <strong>really</strong> appreciate. Thanks guys, you rock.</p> xsawyerx 2010-02-18T10:27:19+00:00 journal On Nagios, Thunk, Shinken and wrapper included marketing http://use.perl.org/~xsawyerx/journal/40153?from=rss <p> <i>original post can be found on my <a href="http://blogs.perl.org/users/sawyer_x/">blog</a>.</i> </p><p> <a href="http://www.nagios.org/">Nagios</a> is probably the most famous and used monitoring program on the market. It's free, GPL and has nice features such as object representation of data, inheritance, plugin systems, passive testing, built-in Perl interpreter, result caching, pipe interface, alert delegations and so on and so on.</p><p>The web interface of Nagios is, however, incredible ugly. It's written in CGI the way the early CGI scripts were written. When you make a change to a server via the web interface, you get a few screens (avoiding Javascript is a benefit for some cell phones, I guess) and the old and quickly-annoying <em>"You have done the action you wanted, please click this back link we created to go backwards"</em> screen. You <strong>won't</strong> simply get automatically directed back to where you were before with a new message at the top in bright green saying <em>"Action X done"</em> or something like that. That would be too easy and <em>Web 2.0</em>. It uses frames (yuck!) to show the sidebar, you don't see the content of comments in hover, only when you <em>click</em> on the comment to get to the <em>comment screen</em> to view the comment. It's literally a pitfall and at least one company where I worked at rewrote the entire interface in ASP and<nobr> <wbr></nobr>.NET (I know, I know...) by parsing the Nagios log.</p><p>For that reason, it has always been a bit difficult (though possible) selling Nagios to the enterprise when your boss isn't tech savvy, and other programs, not much better or worse (<a href="http://www.opennms.org/wiki/Main_Page">OpenNMS</a> for instance) find their way since they have a much better user interface.</p><p>A new fork of Nagios has begun with a PHP interface, calling <a href="http://www.icinga.org/">Icinga</a>. The point is to accept a lot of patches that were difficult to get into Nagios (that has only one actual developer - Ethan Galstad), and provide a beautiful web interface with Javascript. At least one Nagios community members sees the entire fork's point is the web interface, and assumes there's a good chance it will be merged back into Nagios, keeping the core as it is.</p><p>Apparently, there is a Perl <a href="http://www.catalystframework.org/">Catalyst</a>-based project to revamp the Nagios web interface, called <a href="http://github.com/sni/Thruk">Thunk</a>. It is available on Github and also has a <a href="http://thruk-demo.nierlein.de/">demo page</a>. It's incredibly fast and seems promising. However, there is no website for it. Currently the only face it has is the Github page which seems generic and perhaps non-welcoming for some people who consider using it. You can also view the demo, but it still has the basic dull look of Nagios' oldschool interface.</p><p>Another new project relating to Nagios is <a href="http://shinken-monitoring.org/">Shinken</a>, which is a Python rewrite of Nagios. Apparently someone thought that Nagios is great, except it's written in C, which makes it a barrier to include other peoples' work. I personally disagree for a variety of reasons which I won't go into. What does seem interesting is that Shinken is very welcoming, even though (at least to me) it seems like an exercise in futility. I'm assuming it will rapidly develop a stable core userbase, and the website is to thank, IMHO.</p><p>One more issue to note: Ethan Galstad is now developing <a href="http://www.nagios.com/products/nagiosxi/">Nagios XI</a>, an enterprise solution. The "<em>solution</em>" boasts a new <strong>web interface</strong>, which I suspect will be the leading selling point of it.</p><p>So:</p><ul> <li>Nagios has a terrible interface.</li><li>Nagios XI has a pretty interface (and a free iPod Touch with every purchase, according to the site).</li><li>Icinga say they will put more patches in that were rejected or ignored for Nagios (but will keep core compatibility). However the strong point of Icinga (and where most efforts are now going to) is the web interface.</li><li>Thunk attacks the interface problem directly, but doesn't seem it will be adopted much because it doesn't even have a face.</li><li>Shinken tries to replace Nagios by rewriting the core to be in Python, but the best reason to adopt it (as with OpenNMS) is the web interface.</li></ul><p>Now, of course there's a difference in Python, Perl, C and all that. However, in marketing, the selling value goes to the more presentable. In a System Monitoring conference I would have a pretty difficult time selling anything with just a Github page. It all boils down (in marketing terms) to the interface.</p> xsawyerx 2010-02-03T11:39:07+00:00 journal Marketing the Entire Box (including the wrapper) http://use.perl.org/~xsawyerx/journal/40151?from=rss <p> <i>this was originally posted on my new <a href="http://blogs.perl.org/">blogs.perl.org</a> journal, which can be found <a href="http://blogs.perl.org/users/sawyer_x/">here</a>.</i> </p><p>For a long while now I've been wondering about some observations I've made of Perl, Ruby, Python and PHP in marketing terms. I'm going to discuss them here in detail, and I hope it will gain us some insight into better marketing understanding or at least not bore anyone.</p><p>I've understood through the years that projects with beautiful websites have a better chance of getting picked up by users (even when the project itself is purely command-line) and definitely gives much more credit to the encompassing layer (like the programming language itself).</p><p>I've also noticed that a rather large portion of Ruby-related projects have very beautiful websites. You might have noticed this yourself as well. I tried to understand how this situation occurred and had a few discussions at $work with people whose opinion I appreciate, one being a Python and PHP programmer (or, as I like to see him, a programmer who knows PHP) and the other being a Ruby, RoR and overall Javascript whiz.</p><p>At first, my thoughts were that most Ruby programmers major in Rails, so they're into web, while the major web frameworks in Perl (<a href="http://jifty.org/view/HomePage">Jifty</a>, <a href="http://www.catalystframework.org/">Catalyst</a>, <a href="http://search.cpan.org/perldoc?Mojo">Mojo</a>, <a href="http://search.cpan.org/perldoc?Mojolicious">Mojolicious</a>, <a href="http://search.cpan.org/perldoc?Mojolicious::Lite">Mojolicious::Lite</a>, <a href="http://dancer.sukria.net/">Dancer</a>, <a href="http://cgi-app.org/">CGI::Application</a>, etc.) only flowered in recent years, which could lend the thought that most Perl programmers aren't web-oriented or web-aware. I mean this obviously as "aware" in higher extent than most users. As <em>mst</em> eloquently expressed, we're still into IRC (me included, of course).</p><p>Quickly that theory was squashed when I entered the <a href="http://www.djangoproject.com/">Django</a> website. For a web framework, it is horrible. Especially for a web framework that speaks of cleanliness. The website design is horrendous. Same goes for the <a href="http://haml-lang.com/">HAML</a> website. PHP as a very successful web-oriented language shows interesting results. Most PHP programs/scripts come in various index sites (much like oldschool <a href="http://www.perlfoundation.org/perl5/index.cgi?perl_vs_perl">PERL</a> scripts), few PHP frameworks have websites and fewer have beautiful websites. Most of them are awful. Frontpage awful.</p><p>So apparently, dealing with web doesn't mean you create beautiful websites. Yeah, I guess anyone could say that, but to put it in better words: <em> <strong>knowing</strong> web doesn't mean you <strong>do</strong> web.</em> So what is the reason it is almost given that a Ruby project (as small as it might be) will have a website, and it will be beautiful?</p><p>A thought that formed rapidly through the conversations was that Ruby programmers see the marketing as relating to not just the product, but its wrapper. That is, that many Ruby programmers understand at a very core level (more than most programmers - at least me) that the website which shows the project is the actual wrapper of the project and is <em>just as important</em>, if not more so. When I thought of a "nice wrapper", I just thought of a detailed <em>POD</em> and <em>--help</em> output. Obviously, this isn't the case for many Ruby programmers. Those Ruby programmers think <em>"I cannot ship this application without wrapping it nicely, it is just incomplete."</em> </p><p>I began to see the major difference between many Perl programmers and many Ruby programmers. I haven't ever written a website for a project I worked on. Evidently, perhaps many of them don't merit a website of their own, but perhaps some of them do! One of the prime examples for this, IMHO, is <a href="http://lesscss.org/">LessCSS</a> which has a beautiful website for a rather simple filter, which could definitely be accomplished just as well in other languages such as Perl. I thought how simple it would be to write a version in Perl, stepped up to CPAN and here is <a href="http://search.cpan.org/perldoc?CSS::LESSp">CSS::LESSp</a> and <a href="http://search.cpan.org/perldoc?Apache2::Filter::LESS::CSS">Apache2::Filter::LESS::CSS</a>. I have to say that CPAN is indeed comfortable for me, but as a design, it isn't very attractive or compelling. CPAN is an index site, not a front page wrapper for your project.</p><p>When I see the <a href="http://lesscss.org/">LessCSS</a> website, I'm seeing beauty which attracts me not only to <a href="http://lesscss.org/">LessCSS</a> (which I don't really have any use for right now), but also (and <strong>this is key</strong>) to Ruby itself.</p><p>Returning to my quest, I had already sat down with our resident Ruby/Rails expert and a cup of tea and flux-seeds crackers. What I still wondered about was how can a Rails programmer know Ruby, Rails, Javascript (usually) and web design all at once and on such a high level for each to produce such beautiful websites. It's definitely not common, or is it?</p><p>We've laid the foundation that many programmers use prepared (sorry, there is no "pre-prepared" in English) templates and layouts, or hire an actual professional web designer. Hiring a web designer is not a cheap cost. Why are these people spending good sums of money on professional web designers to create (usually static) websites for such small programs? I couldn't understand it.</p><p>Then he mentioned some conventions he went to. When someone shows her peers and future employers projects she has done, the first impression is on the looks of things, not the sound or ability of them. If it's beautiful, she got to first base. If it works much better, but it doesn't even have a face, it stands much less chance of even getting a shot. This is what I was missing.</p><p> <em>Marketing my project is not just marketing a code that does a task, it's marketing <strong>me</strong>!</em> </p><p> <a href="http://dancer.sukria.net/">Dancer</a> doesn't just market a small web framework, it markets Perl and <a href="http://plackperl.org/">Plack</a> (the encompassing technologies), but also the developer(s) of <a href="http://dancer.sukria.net/">Dancer</a>. Same goes for <a href="http://www.catalystframework.org/">Catalyst</a>, same goes for <a href="http://www.iinteractive.com/moose/">Moose</a> and <a href="http://www.iinteractive.com/kiokudb/">KiokuDB</a> and <a href="http://search.cpan.org/perldoc?Module::Starter">Module::Starter</a> and <a href="http://search.cpan.org/perldoc?Test::More">Test::More</a> and on and on and on.</p><p>A response I'm expecting is "well, obviously!" and my answer would be the same, I do know it, however <em> <strong>Understanding</strong> it is much more important than <strong>knowing</strong> it.</em> To <strong>understand</strong> it means to write a website for whatever project I have done which I think can elevate me, and which I think can elevate Perl, or some other encompassing technology (like <a href="http://www.iinteractive.com/moose/">Moose</a> or <a href="http://dancer.sukria.net/">Dancer</a>).</p><p>This morning I imagined having a space for project websites. Actual beautiful static website for each Perl project. I don't have the time to set up an infrastructure for hosting and all that. However, I did purchase PerlProjects.net and I will be giving NS hosting for free to anyone who wants to set up a website at &lt;YourProject&gt;.PerlProjects.net, no matter how small. Also, I want to set up a main site at PerlProjects.net which will be an index of... Perl Projects.</p><p>I do believe that having individual beautiful websites for projects (even the small or relatively exclusive ones) will help market Perl better, and any technology (of Perl or not) you're using in your project. This will help boost interest and consequently the number of programmers who know Perl will go up and of course job offerings will follow. If we can present an image of "Perl projects come in beautiful wrappers", we can present an image of "Perl is beautiful", and that is what we should strive for - at least in marketing terms.</p><p>If you feel like helping with PerlProjects.net (design, design, design) or want your own subdomain and free NS hosting, let me know!</p> xsawyerx 2010-02-02T13:49:25+00:00 journal On low attendance in TelAviv.pm meetings http://use.perl.org/~xsawyerx/journal/40112?from=rss <p> <i>this was originally posted on my new <a href="http://blogs.perl.org/">blogs.perl.org</a> journal, which can be found <a href="http://blogs.perl.org/users/sawyer_x/">here</a>.</i> </p><p>Shlomi Fish <a href="http://community.livejournal.com/shlomif_tech/42895.html">published a post</a> in Israel.pm that I think is worth reading by anyone from Israel (or Israhell), especially if you're from the Tel Aviv region.</p><p>In a year that dealt mostly with marketing, there seemed to be a decline in people showing up to meetings. Even though Tel Aviv University provided us with a room (and now a better room), with a projector, boards, air conditioner and a lot of space, few people show up.</p><p>Whatever the reason is, if these trends continue, the meetings will cease. If you care about Perl, if you like to learn, if you like to teach and if you want to spread it, these meetings are for you (or for you to drag someone else to<nobr> <wbr></nobr>:).</p><p>I find it hard to believe there are no Perl programmers in Tel Aviv (I personally know a few), and that they all know everything already.</p><p>Seriously, wake up and give a shout out to Shlomi (or even me) about why you aren't showing up. Whatever reason it is, there's bound to be some solution to it.</p><p>P.S.:</p><p>No, I didn't really understand what you wanted, Shlomi.<nobr> <wbr></nobr>:) My answer was <em>"whatever parser you want to write, it has two steps. Step one is <code>Parse::RecDescent</code>."</em> I thought it was funny.</p> xsawyerx 2010-01-20T13:15:20+00:00 journal Elegance Fail http://use.perl.org/~xsawyerx/journal/40111?from=rss <p> <i>this was originally posted on my new <a href="http://blogs.perl.org/">blogs.perl.org</a> journal, which can be found <a href="http://blogs.perl.org/users/sawyer_x/">here</a>.</i> </p><p>Elegance might seem like a lost trait in programming these days, but it is live and vibrant in Perl. A rather large part of the <a href="http://search.cpan.org/search?query=test&amp;mode=all">Test</a> namespace is devoted to providing an elegant way to write "run this code, get the result, compare it with this one".</p><p>Today I found myself at a loss of an elegant solution to a problem.</p><p>I want to run a set of tests. Theoretically I can write each subset of tests as a Role in a test object (there are <a href="http://search.cpan.org/perldoc?Test::Class">at</a> <a href="http://search.cpan.org/perldoc?Test::Able">least</a> <a href="http://search.cpan.org/perldoc?Test::Sweet">three</a> testing frameworks that allow this nicely) and then run the tests in the object. I can even use <a href="http://search.cpan.org/perldoc?MooseX::POE">MooseX::POE</a> (or regular <a href="http://search.cpan.org/perldoc?POE">POE</a>, <a href="http://search.cpan.org/perldoc?AnyEvent">AnyEvent</a>, <a href="http://search.cpan.org/perldoc?Test::Aggregate">Test::Aggregate</a> and the list goes on) to run them asynchronously in order to save the time.</p><p>Two things bug me:</p><ul> <li>The majority of the tests count on file content, <em>grep</em>, <em>cat</em>, <em>readlink</em> and such. So basically I'm trying to run simple shell functions inside Perl. I could probably use <a href="http://search.cpan.org/perldoc?Test::File">Test::File</a> for this and expand it to add what's missing.</li><li>I'm testing a remote server, not my own box.</li></ul><p>I can:</p><ul> <li>Write the tests as if they're being run locally. Copy them over, run them and then delete them: I don't like this method. It's unclean.</li><li>Wrap everything in <a href="http://search.cpan.org/perldoc?Net::OpenSSH">Net::OpenSSH</a> (or <a href="http://search.cpan.org/perldoc?POE::Component::OpenSSH">POE::Component::OpenSSH</a>): I don't like this method since it involves a lot of calls just to get the content. Even if I configure my OpenSSH to use a shared socket, it's just wasted ops, ya know?</li><li>Use an RPC server: that means running an RPC server (open iptables for this, of course), rewrite the commands in a long <code>HEREDOC</code> or <code>q{}</code> which is ugly and not very readable.</li></ul><p>What else is there to do?</p><p>Right now the first option (writing the tests, copying them over and running them) seems like the best method because that way I get to write the tests the way I want to and could use <a href="http://search.cpan.org/perldoc?Test::File">Test::File</a> and stuff like that to check what I want. However, I wish there was a more elegant way to solve this. <a href="http://search.cpan.org/perldoc?GRID::Machine">GRID::Machine</a> seems interesting. I could write test subroutines and send their references to the GRID machine.Of course I lose a matter of scoping and would definitely be tricky to manage the inheritance and roles connection I want to use. Frustrating.</p> xsawyerx 2010-01-19T22:22:02+00:00 journal Thoughts on my Moose lecture http://use.perl.org/~xsawyerx/journal/40108?from=rss <p> <i>this was originally posted on my new <a href="http://blogs.perl.org/">blogs.perl.org</a> journal, which can be found <a href="http://blogs.perl.org/users/sawyer_x/">here</a>.</i> </p><p>Yesterday I gave a talk on Moose (the post-modern metaclass-based object system for Perl 5) in TelAviv.pm. The <a href="http://www.slideshare.net/xSawyer/moose-perl-5">slides are available on slideshare</a>. They aren't a lot of slides because I mainly wanted to give an introduction to Moose for beginners and the gist of the lecture is me speaking, so the slides can't really express that.</p><p>Now, regarding the talk. There were few people present, which was a bit unfortunate but I'm assuming it's somewhat due to the change in location in the university. It was difficult to find, I have to admit. However, it's a new place, bigger and more comfortable.</p><p>If I could do it over again, I would definitely want more people and more participation so we could give some live examples instead of trying to squeeze it out of people. But overall, I'm happy with it.</p><p>I scheduled with Gabor to do the lecture on <a href="http://rehovot.pm.org/meetings.html">March in Rehovot.pm</a>. If you're near Rehovot, stop by, say hello and learn how to use Moose!</p><p>I want to thank Shlomi Fish for organizing TelAviv.pm, the lectures (including this one), the promotion, receiving a free guest room from the university and all the other annoying/difficult things most people don't feel like doing.</p> xsawyerx 2010-01-18T09:13:57+00:00 journal Making Dancer Dance on CGI A.K.A. Blog Fix #543 http://use.perl.org/~xsawyerx/journal/40096?from=rss <p> <i>this was originally posted on my new <a href="http://blogs.perl.org/">blogs.perl.org</a> journal, which can be found <a href="http://blogs.perl.org/users/sawyer_x/">here</a>.</i> </p><p>So, <a href="http://blogs.perl.org/users/sawyer_x/2010/01/i-gotz-me-a-dancer.html">last blog entry</a> I mentioned <a href="http://search.cpan.org/perldoc?Dancer">Dancer</a> and that I want to use it as CGI (since it's Plack-aware) but I don't know how.</p><p>Nick Spacek commented on my entry saying that if it supports Plack/PSGI, there should be an easy way to run it as CGI.</p><p>Later that evening I sat down for hummus with my girlfriend (hummus is awesome, ok?). After talking to her about it, I decided to take a minute to check online on my phone if anyone has any explanations on it. In the first 5 results, I found <a href="http://www.sukria.net/fr/archives/2010/01/11/using-plack-to-run-a-dancer-app-under-a-cgi-environment/">a post</a> Alexis Sukriah (who wrote Dancer!) wrote that same day, regarding my post, showing how to use Plack to run a Dancer app under CGI!</p><p>Case in point:</p><blockquote><div><p> <tt>use Plack::Server::CGI;<br>use Plack::Util;<br> <br>my $psgi = '/path/to/your/app/app.psgi';<br>my $app = Plack::Util::load_psgi($psgi);<br>Plack::Server::CGI-&gt;new-&gt;run($app);</tt></p></div> </blockquote><p>... and the web server configuration to use it.<br> (example shown on Alexis' post)</p><p> account with lotsa forks and cares very much about community and communal programming. I have to say, that's a major high point in any module/program/framework I want to use.</p><p>So, I stand corrected. Plack is awesomer than originally thought.</p><p>miyagawa++, sukriah++<nobr> <wbr></nobr>:)</p> xsawyerx 2010-01-12T17:35:33+00:00 journal Hello Clarity http://use.perl.org/~xsawyerx/journal/40092?from=rss <p> <i>this was originally posted on my new <a href="http://blogs.perl.org/">blogs.perl.org</a> journal, which can be found <a href="http://blogs.perl.org/users/sawyer_x/">here</a>.</i> </p><p>For two weeks we've been working hard on defining a rather complex construct of DNS zone files, using multiple servers for multiple domains with cross referencing them and a lot of other complex-sounding terms.</p><p>We wrote DNS tests for the zones to make sure all the servers are configured correctly and the general DNS fetching provides correct information. This turned out to be quite difficult.</p><p>The original script is 130 lines. This is without taking into account even more testing we wanted. There was a lot of analyzing done which was rather repetitive and the overall code was ugly and not fun to read (to put it in mild terms). I decided to write a testing module for DNS zones - Test::DNS.</p><p>Using Test::DNS, we rewrote the script with a lot more options, which we wanted. The resulting script (with the addons) is 20 lines. It's clean and readable.</p><p>Here is how Test::DNS looks:</p><blockquote><div><p> <tt>use Test::More tests =&gt; 5 * $num_of_domains;<br>use Test::DNS;<br>my $dns = Test::DNS-&gt;new();<br>foreach my $domain (@domains) {<br>&nbsp; &nbsp; # assuming $domain is an object<br>&nbsp; &nbsp; $dns-&gt;is_ptr( $domain-&gt;ns1 =&gt; $domain-&gt;ptr1 );<br>&nbsp; &nbsp; $dns-&gt;is_ptr( $domain-&gt;ns2 =&gt; $domain-&gt;ptr2 );<br> <br>&nbsp; &nbsp; $dns-&gt;is_ns( $domain =&gt; [ map { "ns$_.$domain" } 1<nobr> <wbr></nobr>.. 2 ] );<br> <br>&nbsp; &nbsp; # assuming there's overloading here<br>&nbsp; &nbsp; $dns-&gt;is_a( "ns1.$domain" =&gt; $domain-&gt;ns1 );<br>&nbsp; &nbsp; $dns-&gt;is_a( "ns2.$domain" =&gt; $domain-&gt;ns2 );<br> <br>}</tt></p></div> </blockquote><p>Test::DNS will be available soon on CPAN.</p><p>Enjoy!</p> xsawyerx 2010-01-12T08:44:17+00:00 journal I Gotz Me a Dancer http://use.perl.org/~xsawyerx/journal/40091?from=rss <p> <i>this was originally posted on my new <a href="http://blogs.perl.org/">blogs.perl.org</a> journal, which can be found <a href="http://blogs.perl.org/users/sawyer_x/">here</a>.</i> </p><p>Sometimes a good time means relaxing with CPAN, reading a POD of something and trying to learn it. At least for me.</p><p>Last weekend I treated myself to playing with <a href="http://search.cpan.org/perldoc?KiokuDB">KiokuDB</a> and <a href="http://search.cpan.org/perldoc?Dancer">Dancer</a>. I'll write on <a href="http://search.cpan.org/perldoc?KiokuDB">KiokuDB</a> later, this post is on <a href="http://search.cpan.org/perldoc?Dancer">Dancer</a>.</p><p>Dancer is a Plack-aware web application framework written by Alexis Sukrieh. It has a built-in simple templating system, but supports <a href="http://search.cpan.org/perldoc?Template::Toolkit">Template::Toolkit</a> (a must for me), routes handlers (named matching, regex matching, wildcard matching), simple rapid prototyping and support for multiple configurations and allows separate configurations for separate environments and stages of the software.</p><p>After playing with it for a rather short time, I already implemented CRUD. The code comes out clean (which I love), understandable and simple. Pure joy. You should totally <a href="http://search.cpan.org/perldoc?Dancer">check it out</a>!</p><p>The only problem is that I want to write an interface which will be hosted on someone else's computer, which only supports CGI. I have no idea how to run it as CGI. Any ideas?</p><p> <b>Update:</b> Alexis Sukrieh wrote on how to do this <a href="http://www.sukria.net/fr/archives/2010/01/11/using-plack-to-run-a-dancer-app-under-a-cgi-environment/">here</a>. Next post will reflect this!</p> xsawyerx 2010-01-12T08:42:29+00:00 journal Catalyst, MySQL, SQLite, H::FH, UTF-8 and more http://use.perl.org/~xsawyerx/journal/40046?from=rss <p> <i>this was originally posted on my new <a href="http://blogs.perl.org/">blogs.perl.org</a> journal, which can be found <a href="http://blogs.perl.org/users/sawyer_x/">here</a> which is also the <a href="http://blogs.perl.org/users/sawyer_x/">RSS feed</a> for it.</i> </p><p>I tried to update an online website with some changes. Generally, I run a production and a testing environment. Recently, however, I moved the code from using SQLite to MySQL and did not create a testing DB, so changes that require changing the text on the site are done in production. Not good? I know!</p><p>So the website is built in <a href="http://search.cpan.org/perldoc?Catalyst">Catalyst</a>. Originally used SQLite and then migrated to MySQL (which had to be done manually). It uses <a href="http://search.cpan.org/perldoc?HTML::FormHandler">HTML::FormHandler</a> to display the forms, with a generic CRUD layer I added.</p><p>When trying to load the form, I get weird characters for some of the page. From what I gathered, the data in the MySQL isn't kept in UTF8 but in latin1 but we declare the page as UTF8 encoding. The form isn't displayed in utf8 (which was changed using "use utf8;" in the form<nobr> <wbr></nobr>.pm file, or using <a href="http://search.cpan.org/perldoc?Encode::Guess">Encode::Guess</a> which yielded a better result). David Wheeler has a really interesting article on UTF8 in Perl <a href="http://justatheory.com/computers/programming/perl/utf8_trials.html">here</a>.</p><p>When that didn't work, I decided to convert the entire database to UTF-8. I read it using pure DBI, and using <a href="http://search.cpan.org/perldoc?DBIx::Class">DBIC</a> and explicit utf8 column declaration I inserted each table to a newly create database where the tables are charset UTF-8 with utf-8 collation. That didn't change anything. Apparently the latin1 was fine.</p><p>More investigation revealed that the <a href="http://search.cpan.org/perldoc?HTML::FormHandler::Render::Simple">HTML::FormHandler::Render::Simple</a> was decoding some stuff which was screwing up a lot. Once that was fixed (AKA patching it up), more stuff remained unclear. It was as if H::FH wasn't able to read the correct record from the database. Trying to do it using <code> $c-&gt;model('DB::Table')-&gt;search( { id =&gt; $id } ) </code> worked just fine. Apparently the API in HTML::FormHandler changed or it has a critical bug.</p><p>I should read the manual. There is the manual, tutorial and an intro for it. They are all very very long and complex. They give me a headache. Honestly, I'm more comfortable reading the Perl XS tutorial rather than the current synopsis or ANY documentation of HTML::FormHandler.</p><p>Alas, I'll have to get rid of HTML::FormHandler. It's become so cumbersome I can't be bothered patching it any more even. I don't want to reinvent the form wheel again (because I probably won't put a lot into it). Maybe I'll add a layer on top of FormFu.</p><p>I remember asking <em>mst</em> about forms in <em>#catalyst</em> a long while ago. He said that <em>"forms suck.. some people find FormFu helps make them suck less."</em> I think I understand it better now.</p> xsawyerx 2009-12-22T14:28:58+00:00 journal Presenting Module::Starter 1.54 http://use.perl.org/~xsawyerx/journal/40017?from=rss <p> <i>this was originally posted on my new <a href="http://blogs.perl.org/">blogs.perl.org</a> journal, which can be found <a href="http://blogs.perl.org/users/sawyer_x/">here</a> which is also the <a href="http://blogs.perl.org/users/sawyer_x/">RSS feed</a> for it.</i> </p><p> <a href="http://search.cpan.org/perldoc?Module::Starter">Module::Starter</a> 1.54 was recently released. I felt like blogging a bit about it.</p><p>Module::Starter is one of my favorite projects in the Perl community and on CPAN. I use it whenever I want to start a new module or program. It's very simple (read: beginner-friendly), modest and provides what I don't feel like doing myself. It has boilerplate files, text and tests and keeps updating those with habits that are considered "best practice", such as <a href="http://perlbuzz.com/2009/07/help-end-licensing-under-same-terms-as-perl-itself.html">replacing the default licensing term we use</a>.</p><p>Recently I've had the pleasure and honor of contributing to this project. I've made <a href="http://cpansearch.perl.org/src/PETDANCE/Module-Starter-1.54/Changes">several changes</a> mainly taking care of tickets and patches people submitted, making this release a fixer upper release. Following releases will contain some bigger and more exciting changes.</p><p>I want to take this chance to thank Andy Lester, Ricardo Signes, Shlomi Fish and anyone else involved with Module::Starter. Also, I want to thank some lesser-known contributors to Module::Starter, those that send bug reports, feature requests and patches (on my god, patches *drool*).</p><p>It seems like Ricardo's <a href="http://search.cpan.org/perldoc?Dist::Zilla">Dist::Zilla</a> is the contender for Distribution Manager position, and with just cause. However, I rest assure that there are plenty of people (such as me) who prefer using small specific tools for each job they have. I prefer Module::Starter as a module starter, Module::Build as a Distribution Manager, etc.</p><p>That being said, you should still totally check out <a href="http://search.cpan.org/perldoc?Dist::Zilla">Dist::Zilla</a> and see if it's the right tool for you. But don't worry, <a href="http://search.cpan.org/perldoc?Module::Starter">Module::Starter</a> is not going away.<nobr> <wbr></nobr>:)</p> xsawyerx 2009-12-13T16:49:15+00:00 journal Please stop ignoring tickets http://use.perl.org/~xsawyerx/journal/39999?from=rss <p> <i>this was originally posted on my new <a href="http://blogs.perl.org/">blogs.perl.org</a> journal, which can be found <a href="http://blogs.perl.org/users/sawyer_x/">here</a> which is also the <a href="http://blogs.perl.org/users/sawyer_x/">RSS feed</a> for it.</i> </p><p>It's a lot of fun to contribute to other people's code (especially code you're using) and it's very fulfilling. Some people say it's a downer when your code isn't accepted, and I can understand that. However, the serious downer is when your code gets ignored.</p><p> When I go over a module, I go over the ticket list. When I see a ticket from over a year and it's still "new", it disappoints me and when I contribute to a project and it takes six months to get a reply, it disappoints me.</p><p> I know there are also different types of patches. Some of them complex and take time to test, check, correct and adapt. However, some patches are simple errors, common typos, data that should be added (like another entry for a hash of static data). These shouldn't be stuck so long back there. And, above all, don't ignore the contributor. Go over the tickets <strong>once a month</strong> and see if you can comment on anything. Even saying "I can't address this in the near future" means a lot to the contributor.</p><p>If you feel you don't have the time to work on a project, write about it, and suggest someone (most likely someone you already trust) be able to have co-maintainer status in order to apply some patches and release a new version.</p><p>Often times I see a project and think "well, I could fix this or that" or "seems like these only need applying and testing" but I don't want to take over the leadership of the module. I've contacted a lot of authors over the years. I've gotten only a few replies.</p><p>Sometimes I think releasing Your::Module::Patched will be the only way to get some of the patches I or other authors write included in. Obviously, that isn't a smart move. CPAN isn't Github. It doesn't look kindly on forks because it still has to maintain some authoritative version of a project for users to be able to download. Users want authoritative versions, not "his/her version".</p><p>Other than trying to contact an author, writing an email (or another one) and maintaining a personal collection of patches, I don't know what else can be done.</p><p>Please, give your RT some love, give your contributors some love.</p><p>I think I'll personally try to contact some authors for co-maintainer status just to patch things up.</p> xsawyerx 2009-12-10T13:27:27+00:00 journal Security by Obscurity, DLC style http://use.perl.org/~xsawyerx/journal/39988?from=rss <p> <i>this was originally posted on my new <a href="http://blogs.perl.org/">blogs.perl.org</a> journal, which can be found <a href="http://blogs.perl.org/users/sawyer_x/">here</a> which is also the <a href="http://blogs.perl.org/users/sawyer_x/">RSS feed</a> for it.</i> </p><p> <em>&lt;rant&gt;</em> </p><p>Rapidshare deletes illegal files, so instead of sharing Rapidshare links, sites nowadays apparently started sharing<nobr> <wbr></nobr>.dlc files (or so I've heard). DLC is an encrypted container format. It is very very stupid. I'll elaborate.</p><p>Let's break it down:</p><ul> <li>Only one server decrypts - single point of failure.</li><li>Disregarding the necessity for internet, this binds you to specific programs that have the keys hardcoded in them to be able to access the server.</li><li>The protocol is secret, the key is secret, the programs are closed source (at least the part that matters).</li><li>One program is for Windows only. The main one is written in Java. Stupid Java. I've gone over the parts of it that are open source and it's horrible (really really horrible).</li><li>I have not managed to get the program running on three different computers, and on Windows as well.</li><li>Apparently they change the key every once in a while so you <strong>always</strong> have to stay updated with the program.</li></ul><p>However, these are all implementation issues. The problem here is that a bunch of freelance programmers (I'm assuming) think that by hardcoding and source-closing the key to their wanna-be-open-source application, it will somehow deter people who make it their job to crack it.</p><p>Since you still want the average boob (that is, the average dumbbell) to be able to operate the program and download the stuff, you need to make it accessible enough for him/her. Once it's that accessible, it's accessible to any IRAA/MPAA/&lt;enter agency name&gt; agent to reach as well, since they are <strong>at least</strong> as smart as the average bear, err... boob.</p><p>You're telling me a well funded agency can't open the stupid program and click the link? They can't write a program that automatically opens the other program and clicks the link? Really? Oh, this is ultra super secure now? You can write a Visual Basic program that does that in 10 minutes.<br> <em>(please don't write a visual basic program)</em> </p><p>I've emailed at least one website that does that, trying to get a decent answer for this. Still no response.</p><p>As to the JDownloader developers: Your program doesn't work, and your super ultra secure technology is closed source i-wouldn't-touch-it-with-a-ten-foot-pole icky. Yes, icky. You've secured nothing!</p><p> <a href="http://fox21.at/">Fox21.at</a> [fox21.at] release various Perl programs. One of them is called <a href="http://fox21.at/dlc2txt-100.html">dlc2txt</a> (oh, <a href="http://translate.google.com/translate?js=y&amp;prev=_t&amp;hl=en&amp;ie=UTF-8&amp;layout=1&amp;eotf=1&amp;u=http%3A%2F%2Ffox21.at%2Fdlc2txt-100.html&amp;sl=de&amp;tl=en">here's the Google Translate for it</a>). Using this program, given the key and host, you can just crack DLC files yourself.</p><p>Of course the developers keep the key in JDownloader only. They also issues two other keys for two other programs (one of them written in Python) and threatened them not to reveal the key. The other programs and JDownloader keep the key closed source by compiling it.</p><p>So you have to use JDownloader or the other programs.<br> Right? Wrong!</p><p> <a href="http://translate.googleusercontent.com/translate_c?hl=en&amp;ie=UTF-8&amp;sl=de&amp;tl=en&amp;u=http://eddy14.freeunix.net/blog/2008/11/15/dlc-geknackt/&amp;prev=_t&amp;rurl=translate.google.com&amp;twu=1&amp;usg=ALkJrhihDldSbgVkdpmJMM4rE4Jy5khahQ">Here is a fully detailed post</a> on how to crack DLC completely.</p><p>I will probably write a Perl module to use <a href="http://www.decryptdlc.info/">this new kickass webservice</a> that cracks DLC for you.</p><p>Meanwhile, please quit trying to convince people that your new thinga-ma-gic protects them even though it really doesn't. It only adds complexity for the user (much more than for an agent) and pisses people (like me) off.</p><p>Thank you.</p><p> <em>&lt;/rant&gt;</em> </p> xsawyerx 2009-12-08T09:45:19+00:00 journal I'm moving on up! (... or simply away) http://use.perl.org/~xsawyerx/journal/39963?from=rss <p>I'm seriously sick of use.perl.org. I liked it when I just started blogging (<i>id est</i> bitching), it was fine. However, soon enough I wanted to write a blog entry without writing all the HTML code myself, without writing in a <b>really</b> small textarea, without working really hard on writing even the smallest post... and damn, I wanted some interface that wasn't this ugly.</p><p>In the Perl world, we now work very hard on being "less ugly" because many of us are system-oriented people. We don't see pretty or ugly, but other people do, and it makes them stray away from our technology.</p><p> <a href="http://blogs.perl.org/">Blogs.Perl.Org</a> looks the way blogging in Perl-world should look like. I'm moving there. I might cross-post here as well, I might not.</p><p>The live feed for <b>blogs.perl.org</b> is <a href="http://blogs.perl.org/atom.xml">http://blogs.perl.org/atom.xml</a>. Use it!</p><p>My personal blog there is under <i>Sawyer X</i>. I'll have Perl Sphere updated with my new blog as well.</p><p> <i>See ya on the flip side...</i></p> xsawyerx 2009-11-30T08:26:21+00:00 journal Extensive POE Testing PT. 7 - Testing, Event Parameters PT.2 http://use.perl.org/~xsawyerx/journal/39840?from=rss <i>There is actually a limit on the length of the subject, this should actually be entitled: <b>Extensive POE Testing PT. 7 - Testing, Unordered Event Parameters</b> </i> <p> <a href="http://use.perl.org/~xsawyerx/journal/39811">Last post</a> talked about <b>Ordered Event Parameter testing</b> which is basically setting a set of parameters that should be for each event, in the order in which they are suppose to be run.</p><p>A weak point that remains in this rather strong testing feature is the ability to make it unordered. That is, to say <i>"I know the event <b>next</b> will be called with each of these parameter sets, but I don't know <b>which</b> one will come before the other.</i></p><p>A good example would be two events (one could even be an alarm) were to reach the same event, each with different parameters:</p><blockquote><div><p> <tt>package Session;<br>use MooseX::POE;<br>sub START {<br>&nbsp; &nbsp; $_[KERNEL]-&gt;alarm( 'mine_alarmz', time() + int rand 2 );<br>&nbsp; &nbsp; #<nobr> <wbr></nobr>... other stuff<br>&nbsp; &nbsp; $_[KERNEL]-&gt;yield( 'next', 'from START' );<br>}<br> <br>event 'mine_alarmz' =&gt; sub {<br>&nbsp; &nbsp; $_[KERNEL]-&gt;yield( 'next', 'from alarmz' );<br>};</tt></p></div> </blockquote><p>The race condition here manifests by having two codes (START, alarm) running the same event (next) and not knowing for sure which will reach it first.</p><p>In this case, testing for the set of parameters <i>next</i> will be called with (especially in a specific order) will be worthless. Taking into account that we don't really care what set of parameters is called first, setting <b>possible sets of parameters</b> for <i>next</i> will make sure that when it is called, it will not be called with anything that isn't defined as a set of parameters and will allow this race condition to exist, without causing trouble. This is actually the preferable method of testing event parameters for most people.</p><p>When using <a href="http://search.cpan.org/perldoc?POE::Test::Helpers">POE::Test::Helpers</a> to do it, you merely have to override another attribute to set it. Here is a sample:</p><blockquote><div><p> <tt>package Session;<br>use Test::More tests =&gt; 4;<br>use MooseX::POE;<br>with 'POE::Test::Helpers';<br>has '+event_params' =&gt; (<br>&nbsp; &nbsp; default =&gt; sub { {<br>&nbsp; &nbsp; &nbsp; &nbsp; 'next' =&gt; [ [ 'hello', 'world' ], [ 'goodbye' ] ],<br>&nbsp; &nbsp; &nbsp; &nbsp; 'more' =&gt; [ [] ],<br>} } );<br> <br># this is the new attribute to override<br>has '+event_params_type' =&gt; ( default =&gt; 'unordered' );<br> <br>my $flag = 0;<br>sub START&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ $_[KERNEL]-&gt;yield( 'next', 'goodbye' ) }<br>event 'next' =&gt; sub { $_[KERNEL]-&gt;yield( 'more'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) };<br>event 'more' =&gt; sub {<br>&nbsp; &nbsp; $flag++ || $_[KERNEL]-&gt;yield( 'next', 'hello', 'world' );<br>};<br> <br>package main;<br>use POE::Kernel;<br>Session-&gt;new();<br>POE::Kernel-&gt;run();</tt></p></div> </blockquote><p>Next post (hopefully won't be in too long) will cover writing some tests with <a href="http://search.cpan.org/perldoc?POE::Test::Helpers">POE::Test::Helpers</a> </p> xsawyerx 2009-11-04T15:47:36+00:00 journal Extensive POE Testing PT. 6 - Testing, Event Parameters PT.1 http://use.perl.org/~xsawyerx/journal/39811?from=rss <i>There is actually a limit on the length of the subject, this should actually be entitled: <b>Extensive POE Testing PT. 6 - Testing, Ordered Event Parameters</b> </i> <p>We've covered <a href="http://use.perl.org/~xsawyerx/journal/39727">the rules</a>, <a href="http://use.perl.org/~xsawyerx/journal/39734">ordered tests</a>, <a href="http://use.perl.org/~xsawyerx/journal/39739">sequence ordered tests</a>, <a href="http://use.perl.org/~xsawyerx/journal/39768">event counting</a> and <a href="http://use.perl.org/~xsawyerx/journal/39775">a mixture of event counting and sequence ordered tests</a>. Now it's time to play with some more advanced stuff.</p><p>The last frontier I came across trying to battle testing in POE was wanting to make sure the parameters to each event were what I expected. Why?</p><ul> <li>I'm able to test who called what and how many times, but if the parameters change, how would I know?</li><li>What if there an error in a function that's hard to test and it calls incorrect parameters?</li><li>What if I have a race condition?</li></ul><p>So, naturally, I wanted to know what parameters are sent to each event. This is how it can be done with my <a href="http://search.cpan.org/perldoc?POE::Test::Helpers">POE::Test::Helpers</a> 0.06:</p><blockquote><div><p> <tt>package Session;<br>use Test::More tests =&gt; 4; # this can also be defined in main<br>use MooseX::POE;<br>with 'POE::Test::Helpers';<br> <br>has '+event_params' =&gt; ( default =&gt; sub { {<br>&nbsp; &nbsp; next =&gt; [ [ 'hello', 'world' ], [ 'goodbye' ] ],<br>&nbsp; &nbsp; more =&gt; [],<br>} } );<br> <br># a flag for making sure next runs again<br>my $flag = 0;<br> <br># set up the events<br>sub START { $_[KERNEL]-&gt;yield( 'next', qw( hello world ) ) }<br> <br>event 'next' =&gt; sub { $_[KERNEL]-&gt;yield('more') };<br>event 'more' =&gt; sub {<br>&nbsp; &nbsp; $flag++ || $_[KERNEL]-&gt;yield( 'next', 'goodbye' );<br>};<br> <br># set up main<br>package main;<br>use POE::Kernel;<br>Session-&gt;new();<br>POE::Kernel-&gt;run();</tt></p></div> </blockquote><p>What happens when the Kernel is run is that:</p><ul> <li> <i>START</i> -&gt; <i>next</i> (parameters: "hello", "world") </li><li> <i>next</i> -&gt; <i>more</i> (no parameters)</li><li> <i>more</i> -&gt; <i>next</i> (parameters: "goodbye")</li><li> <i>next</i> -&gt; <i>more</i> (no parameters)</li><li> <i>more</i> does nothing and the program closes.</li></ul><p>What we can see is that we defined with our helpers the assumed iterations of each event. <i>next</i> is assumed to <b>first</b> run with the parameters "hello" and "world", and <b>secondly</b> run with the parameter "goodbye". We also assume that <i>more</i> will be called with no parameters at all.</p><p>These are the results of the test:</p><blockquote><div><p> <tt>1..4<br>ok 1 - (next) Correct params<br>ok 2 - (more) Correct params<br>ok 3 - (next) Correct params<br>ok 4 - (more) Correct params</tt></p></div> </blockquote><p>This helps make sure the events run with the exact parameters we want <b>for each run</b>, <b>in the order we specified</b>. This is extremely important to understand. It checks that you called it <b>first</b> with the first parameter set (in an arrayref) and only <b>then</b> with the <b>second</b> one. If by some weird turn of events (or code editing), the calls would get mixed up and it will call <i>next</i> with "goodbye" first, the test will fail.</p><p>This is how it would look if we reverse the order of the parameters:</p><blockquote><div><p> <tt>not ok 1 - (next) Correct params<br>#&nbsp; &nbsp;Failed test '(next) Correct params'<br>#&nbsp; &nbsp;at lib/POE/Test/Helpers.pm line 94.<br># Comparing $data as a Bag<br># Missing: 'goodbye'<br># Extra: 'hello', 'world'<br>ok 2 - (more) Correct params<br>not ok 3 - (next) Correct params<br>#&nbsp; &nbsp;Failed test '(next) Correct params'<br>#&nbsp; &nbsp;at lib/POE/Test/Helpers.pm line 94.<br># Comparing $data as a Bag<br># Missing: 'hello', 'world'<br># Extra: 'goodbye'<br>ok 4 - (more) Correct params<br># Looks like you failed 2 tests of 4.</tt></p></div> </blockquote><p>One question remains: what if I can't know the order? What if I don't care? What if either of them can run but I don't know which one would come before the other? That's left for the next post.</p><p> <i>BTW, as promised, I will demonstrate how to test for a pretty nasty race condition using these methods, easily.</i></p> xsawyerx 2009-10-28T08:27:52+00:00 journal Extensive POE Testing PT. 5 - Testing, Seq-Ordered and Count http://use.perl.org/~xsawyerx/journal/39775?from=rss <i>dngor corrected me on some errors in the last post. they were fixed.</i> <p>This is a short post in my series. It simply shows how to combine (using POE::Test::Helpers) both <b>sequence ordered</b> tests and <b>event counting<b> tests at the same time.</b></b></p><blockquote><div><p> <tt># drawing from a previous example:<br>package Session;<br>use MooseX::POE;<br>use Test::More;<br>with 'POE::Test::Helpers'; # actual title<br> <br>has '+seq_ordering' =&gt; ( default =&gt; sub { {<br>&nbsp; &nbsp; START =&gt; 1,<br>&nbsp; &nbsp; next&nbsp; =&gt; 4,<br>&nbsp; &nbsp; more&nbsp; =&gt; 4,<br>&nbsp; &nbsp; last&nbsp; =&gt; { 1 =&gt; [ 'START', 'next', 'more' ] },<br>&nbsp; &nbsp; STOP&nbsp; =&gt; [ 'START', 'next', 'more', 'last' ],<br>} } );<br> <br>my $count = 0;<br>sub START&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ $_[KERNEL]-&gt;yield('next') }<br>event 'next' =&gt; sub { $_[KERNEL]-&gt;yield('more') };<br>event 'more' =&gt; sub {<br>&nbsp; &nbsp; $count++ &lt; 3 ? $_[KERNEL]-&gt;yield('next')<nobr> <wbr></nobr>:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$_[KERNEL]-&gt;yield('last');<br>};<br>event 'last' =&gt; sub { 1 };<br> <br># adding the runner<br>package main;<br>use Test::More tests =&gt; 6;<br>use POE::Kernel;<br> <br>Session-&gt;new();<br>POE::Kernel-&gt;run();</tt></p></div> </blockquote><p>Here we can see how our test requirements are declared:</p><ul> <li> <i>START</i> runs only once</li><li> <i>next</i> runs four times</li><li> <i>more</i> runs four times</li><li> <i>last</i> runs once</li><li> <i>last</i> runs ONLY after <i>START</i>, <i>next</i> and <i>more</i> </li><li> <i>STOP</i> runs only after all the other events</li></ul><p>That comes out to 6 tests. That's what we wrote in the Test::More plan and this is the result:</p><blockquote><div><p> <tt>$ perl -Ilib t/articles/2.t<br>1..6<br>ok 1 - Correct sequence for last<br>ok 2 - Correct sequence for STOP<br>ok 3 - (next) Correct number of runs<br>ok 4 - (START) Correct number of runs<br>ok 5 - (last) Correct number of runs<br>ok 6 - (more) Correct number of runs</tt></p></div> </blockquote><p>We can see that it only tested <i>last</i> and <i>STOP</i> for <b>sequence ordering</b> (or <b>event dependency</b>). Also, it only checked the number of correct runs on <i>next</i>, <i>START</i>, <i>last</i> and <i>more</i>.</p><p>You might notice the test output didn't come out in the same order the events ran. That's because it takes them from the attribute we set, which is a hash and hence, has no order.</p><p> <b>What next?</b> <br> While I'm working on releasing it today to Github and hopefully soon enough to CPAN as well, I still have a few things to go over. There's one more type of tests that I found the most important for me and it's pretty sweet. I intend to write another post or two on that. Then I'm going to present the framework (it should already be on CPAN by that time) and show a pretty insane race condition we found at $work and tested using this framework. Stay tuned!</p> xsawyerx 2009-10-20T08:39:52+00:00 journal Extensive POE Testing PT. 4 - Testing, Event Count http://use.perl.org/~xsawyerx/journal/39768?from=rss <i>update: fixed a few errors</i> <p>So it took some time, but here's the next article/post on POE testing.</p><p>The <a href="http://use.perl.org/~xsawyerx/journal/39739">last one</a> discussed <b>Sequence Ordered</b> tests, which is the way I call the type of tests that do not rely on whether the event ran at the specified order by number, but <i>by previously running events</i>. However, all the previous posts still ignored a serious need that we have for event testing, which is <i>how many times did each event really run?</i> </p><p>If you use <b>ordered tests</b>, you cannot have the same event running more than once without some logic to test the specific iteration of the event. <b>sequence ordered tests</b> help reduce that but they also reduce the count.</p><p>Let us take a look at code which runs the same event more than once:</p><blockquote><div><p> <tt>package Session;<br>use MooseX::POE;<br> <br>my $count&nbsp; = 0;<br> <br>sub START&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ $_[KERNEL]-&gt;yield('next')&nbsp; }<br>event 'next' =&gt; sub { $_[KERNEL]-&gt;yield('more')&nbsp; };<br> <br>event 'more' =&gt; sub {<br>&nbsp; &nbsp; $count++ &lt; 3 ? $_[KERNEL]-&gt;yield('next')<nobr> <wbr></nobr>:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$_[KERNEL]-&gt;yield('last');<br>};<br> <br>event 'last' =&gt; sub { print "last!\n"; };</tt></p></div> </blockquote><p>Now let's add tests:</p><blockquote><div><p> <tt>package Session;<br>use MooseX::POE;<br>use Test::More tests =&gt; 4;<br> <br>my %events = ();<br>my $count&nbsp; = 0;<br> <br>sub START {<br>&nbsp; &nbsp; $events{'START'}++;<br>&nbsp; &nbsp; $_[KERNEL]-&gt;yield('next');<br>}<br> <br>event 'next' =&gt; sub {<br>&nbsp; &nbsp; $events{'next'}++;<br>&nbsp; &nbsp; $_[KERNEL]-&gt;yield('more');<br>};<br> <br>event 'more' =&gt; sub {<br>&nbsp; &nbsp; $events{'more'}++;<br>&nbsp; &nbsp; $count++ &lt; 3 ? $_[KERNEL]-&gt;yield('next')<nobr> <wbr></nobr>:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$_[KERNEL]-&gt;yield('last');<br>};<br> <br>event 'last' =&gt; sub {<br>&nbsp; &nbsp; $events{'last'}++;<br>&nbsp; &nbsp; print "last!\n";<br>};<br> <br>event 'STOP' =&gt; sub {<br>&nbsp; &nbsp; cmp_ok( $events{'START'}, '==', 1, 'START ran once'&nbsp; &nbsp;);<br>&nbsp; &nbsp; cmp_ok( $events{'next'},&nbsp; '==', 4, 'next ran 4 times' );<br>&nbsp; &nbsp; cmp_ok( $events{'more'},&nbsp; '==', 4, 'last ran 4 times' );<br>&nbsp; &nbsp; cmp_ok( $events{'last'},&nbsp; '==', 1, 'last ran once'&nbsp; &nbsp; );<br>};</tt></p></div> </blockquote><p>This is how we could accomplish it. Here is how it's done with the current iteration of my (still yet unpublished) testing framework:</p><blockquote><div><p> <tt>package Session;<br>use MooseX::POE;<br>use Test::More tests =&gt; 4;<br>with 'POE::Test::Simple'; # running title<br> <br>has '+seq_ordering' =&gt; ( default =&gt; sub { {<br>&nbsp; &nbsp; START =&gt; 1,<br>&nbsp; &nbsp; next&nbsp; =&gt; 4,<br>&nbsp; &nbsp; more&nbsp; =&gt; 4,<br>&nbsp; &nbsp; last&nbsp; =&gt; 1,<br>} } );<br> <br>my $count = 0;<br> <br>sub START {<br>&nbsp; &nbsp; $_[OBJECT]-&gt;seq_order('START');<br>&nbsp; &nbsp; $_[KERNEL]-&gt;yield('next');<br>}<br> <br>event 'next' =&gt; sub {<br>&nbsp; &nbsp; $_[OBJECT]-&gt;seq_order('next');<br>&nbsp; &nbsp; $_[KERNEL]-&gt;yield('more');<br>};<br> <br>event 'more' =&gt; sub {<br>&nbsp; &nbsp; $_[OBJECT]-&gt;seq_order('more');<br>&nbsp; &nbsp; $count++ &lt; 3 ? $_[KERNEL]-&gt;yield('next')<nobr> <wbr></nobr>:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$_[KERNEL]-&gt;yield('last');<br>};<br> <br>event 'last' =&gt; sub {<br>&nbsp; &nbsp; $_[OBJECT]-&gt;seq_order('last');<br>&nbsp; &nbsp; print "last!\n";<br>};<br> <br>event 'STOP' =&gt; sub {<br>&nbsp; &nbsp; $_[OBJECT]-&gt;seq_end();<br>};</tt></p></div> </blockquote><p>And this is how it would look in the (hopefully) upcoming version:</p><blockquote><div><p> <tt>package Session;<br>use MooseX::POE;<br>use Test::More tests =&gt; 4;<br>with 'POE::Test::Simple'; # running title<br> <br>has '+seq_ordering' =&gt; ( default =&gt; sub { {<br>&nbsp; &nbsp; START =&gt; 1,<br>&nbsp; &nbsp; next&nbsp; =&gt; 4,<br>&nbsp; &nbsp; more&nbsp; =&gt; 4,<br>&nbsp; &nbsp; last&nbsp; =&gt; 1,<br>} } );<br> <br>my $count = 0;<br> <br>sub START&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ $_[KERNEL]-&gt;yield('next') }<br>event 'next' =&gt; sub { $_[KERNEL]-&gt;yield('more') };<br> <br>event 'more' =&gt; sub {<br>&nbsp; &nbsp; $count++ &lt; 3 ? $_[KERNEL]-&gt;yield('next')<nobr> <wbr></nobr>:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$_[KERNEL]-&gt;yield('last');<br>};<br> <br>event 'last' =&gt; sub { print "last!\n" };</tt></p></div> </blockquote><p>Next post is a short one in which I'll show samples of using both event counting and sequence order (event dependencies).</p> xsawyerx 2009-10-18T11:43:02+00:00 journal Extensive POE Testing PT. 3 - Testing, Sequence Ordered http://use.perl.org/~xsawyerx/journal/39739?from=rss <p>My <a href="http://use.perl.org/~xsawyerx/journal/39734">last post</a> went over the idea of ordered tests, in which we run events in a certain order. It's a simple concept, it's easy to test and it's very nifty.</p><p>However, it fails to cover some more advanced grounds, specifically the idea of multiple runtimes of a session or event, in which we can result in a race condition where two or more instances of the event will try to fire first and we aren't exactly sure which will come first. One could stumble over an <code>if()</code> that will take it a little bit more while the other might handle an unexpected delay because of its flow.</p><p>Still, the point to make is that usually in such situations we don't really care what was the <b>numbered order</b> of the events, we care about the <b>preceeding order</b> of the events. Meaning, the <b>sequence of events</b>.</p><p>Here is an example:</p><blockquote><div><p> <tt>package MyPackage;<br>use MooseX::POE;<br> <br>has 'num' =&gt; ( is =&gt; 'ro', isa =&gt; 'Int', default =&gt; 0 );<br> <br>sub START { # in MX::POE, this is mapped to _start<br>&nbsp; &nbsp; $_[KERNEL]-&gt;yield('first');<br>}<br> <br>event 'first' =&gt; sub {<br>&nbsp; &nbsp; if ( $_[OBJECT]-&gt;num == 7 ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; # lucky number slevin<br>&nbsp; &nbsp; &nbsp; &nbsp; $_[KERNEL]-&gt;yield('long_taking_event');<br>&nbsp; &nbsp; }<br> <br>&nbsp; &nbsp; $_[KERNEL]-&gt;yield('second');<br>};<br> <br>event 'second' =&gt; sub {<br>&nbsp; &nbsp; print "reached second!\n";<br>};<br> <br>event 'long_taking_event' =&gt; sub {<br>&nbsp; &nbsp; print "reached long taking event!\n";<br>};<br> <br>package main;<br>MyPackage-&gt;new( num =&gt; rand(10) ) for 1<nobr> <wbr></nobr>.. 5;</tt></p></div> </blockquote><p>In this example, we aren't exactly sure if <code>num</code> will be 7 or not, and thus we aren't sure if <code>long_taking_event</code> will even be called. Besides, we're running each event more than once so the <code>order</code> function with the static number of running order of the events cannot even be applied here.</p><p>Interestingly enough, we can stipulate that we do know <code>first</code> is suppose to run only after <code>START</code>. This might seem a bit given, but maybe we've made an error in the code and run <code>first</code> directly? How about knowing that <code>long_taking_event</code> and <code>second</code> can only be run after <code>first</code>? That's pretty good to know. If we run the program and it will see that <code>second</code> ran <b>before</b> <code>first</code>, we know we've made a mistake!</p><p>That's what I call <b>sequenced-ordered tests</b> or <b>event-dependency order</b>. It's when the order isn't conclusive, but the sequence of events is. Right now my (yet unnamed and unpublished) framework supports that in a very simple form:</p><blockquote><div><p> <tt>with 'POE::Test::Simple'; # running title<br> <br>has '+seq_ordering' =&gt; ( default =&gt; sub { {<br>&nbsp; &nbsp; 'first'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =&gt; [ 'START'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],<br>&nbsp; &nbsp; 'second'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=&gt; [ 'START', 'first' ],<br>&nbsp; &nbsp; 'long_taking_event =&gt; [ 'START', 'first' ],<br>} } );<br> <br># then each event/sub called can register itself with the framework<br>event 'second' =&gt; sub {<br>&nbsp; &nbsp; $_[OBJECT]-&gt;seq_order('second');<br>};</tt></p></div> </blockquote><p>Right now I'm working on making this implicit so it's not required to run at all in order for the testing to run. Much help on this came from <code>mst</code>, <code>doy</code> and other great people at <code>#moose</code>. Thanks guys!</p><p>Again, thinking about what this still misses: <i>how many times each event ran?</i> We have no counting of this, so the next post will cover <b>event counting</b>, which is exactly it. Meanwhile, if you feel like pitching ideas for the framework module name, I'd appreciate it.</p> xsawyerx 2009-10-11T09:42:27+00:00 journal Extensive POE Testing PT. 2 - Testing, Ordered http://use.perl.org/~xsawyerx/journal/39734?from=rss <i>A special thanks goes here to Adam Kennedy for sending me on this path and giving me ideas. Adam, I wanted to thank you personally but couldn't catch you on IRC, so thanks!<nobr> <wbr></nobr>:)</i> <p>I tried to cover in my <a href="http://use.perl.org/~xsawyerx/journal/39727">last post</a> the basic guidelines I have for testing in <a href="http://search.cpan.org/perldoc?POE">POE</a>. Testing in <a href="http://search.cpan.org/perldoc?POE">POE</a> is different since we want to test a flow and not just subroutines. This time I want to try go over the first type of tests that I find necessary. It's called <b>ordered tests</b> - at least that's how I call it.</p><p>This method was first hinted at me by the great Adam Kennedy who used it in his <a href="http://search.cpan.org/perldoc?POE::Declare">POE::Declare</a> module. Basically it describes the following scenario: I have a <a href="http://search.cpan.org/perldoc?POE::Sesson">POE::Session</a> event flow and I want to make sure that every event is run at the specific order.</p><blockquote><div><p> <tt>package MyPackage;<br>use MooseX::POE;<br>use Test::More;<br> <br># this is taken from POE::Declare's t/04-stop.t<br>my $order = 0;<br>sub order {<br>&nbsp; &nbsp; my $position = shift;<br>&nbsp; &nbsp; my $message&nbsp; = shift;<br>&nbsp; &nbsp; is( $order++, $position, "$message ($position)" );<br>}<br> <br># then we can do this (written in MX::POE)<br>event 'eg' =&gt; sub {<br>&nbsp; &nbsp; order( 0, 'Started eg event' );<br>};</tt></p></div> </blockquote><p>Now, each event could run this subroutine with a number indicating the order of this event in our overall flow of the session. Here, for example, with the <code>order( 0, 'event name' )</code> code if any event is running at a time that wasn't meant for it, it will fail.</p><p>However, it has a few disadvantages:</p><ul> <li>If any of the events repeat, it creates a problem. You'll have to set up a system to check which iteration of the event it is and execute the correct <code>order()</code> </li><li>What if you're yelding the kernel for two events and you aren't sure which one will run first?</li><li>What if it doesn't matter which one will run first?</li><li>What about running two sessions of the same object? It has the exact same events, with the exact same code. It will fail for sure.</li></ul><p>My suggestion: allow a test that checks for event dependency. Instead of saying "this runs first", you could say "this runs ONLY after that" and "this - this runs only after these two". That would allow to have an order based on a sequence of events. Each event can only come after different events.</p><p>This is what the next post will discuss.</p> xsawyerx 2009-10-09T14:32:50+00:00 journal Extensive POE Testing PT. 1 - The Rules http://use.perl.org/~xsawyerx/journal/39727?from=rss <p> <i> If you only use <a href="http://search.cpan.org/perldoc?POE::Session">POE::Session</a> for your <a href="http://search.cpan.org/perldoc?POE">POE</a> code and find no need for more elaborate tests, feel free to skip these posts. I won't be offended, I promise.<nobr> <wbr></nobr>:) </i> </p><p> After a lot of frustration of trying to set up proper tests for <a href="http://search.cpan.org/perldoc?POE">POE</a> (using mainly <a href="http://search.cpan.org/perldoc?MooseX::POE">MooseX::POE</a> while at it), I've decided to write a proper testing framework. However, instead I wrote something simple, yet relatively extensive that helps write fingergrained tests for <a href="http://search.cpan.org/perldoc?POE">POE</a> using <a href="http://search.cpan.org/perldoc?Moose">Moose</a>, specifically aimed towards <a href="http://search.cpan.org/perldoc?MooseX::POE">MooseX::POE</a>. </p><p> I've decided to write it in <a href="http://search.cpan.org/perldoc?Moose">Moose</a> (using <a href="http://search.cpan.org/perldoc?Moose::Role">Moose::Role</a>) because it makes it much easier for me to do it than other frameworks/modules. I don't intend (at least at this time) to write it in bare bones Perl and I personally don't care about complete optimizations for my testing code, I don't think a lot of people would mind either. </p><p> This article will only discuss the general need, the idea and the general rules I've layed out for myself to help me test <a href="http://search.cpan.org/perldoc?POE">POE</a> code. It might help you too. The following articles in this series (and I assure you, there will be!) discuss the types of tests that I feel are required and examples of code that does it. I'll also present my new (unnamed) testing framework that's already being used at $work. </p><p> <b>Preliminary:</b> <br> In <a href="http://search.cpan.org/perldoc?POE">POE</a>, you have a layer of "events" which are actually just mappings of names of events that can be run to the actual subroutines that they will trigger when run. This seems pretty simple to test. You can check each subroutine separately and that's just fine. However, there are some things it doesn't cover:</p><ul> <li> <a href="http://search.cpan.org/perldoc?MooseX::POE">MooseX::POE</a>: if you're using <a href="http://search.cpan.org/perldoc?MooseX::POE">MooseX::POE</a> your events are mapped for you to anonymous subroutines. Instead of writing a named subroutine and then mapping it through <code>inline_states</code> (or whatever), you simply do <code>event 'something' =&gt; sub {};</code> Problem is, you cannot test it that easily.</li><li>Sometimes you want to run stuff and see how it works: It is important to test every small component separately, but it's always nice (especially when it comes to complete environments) to check a bigger chunk. It's also easier to comprehend. Sure, I know that check_stuff() was run, but when the program was started, did it get run 3 or 4 times?</li><li>Some things are harder [and/or take longer] to test. For example, suppose a subroutine can be called several times (loop, events, alarm) with varying inputs. Perhaps there's an alarm that checks each time and only then runs another event. To test every subroutine's possible iteration is possible, but not as much fun.</li></ul><p> <b>Theory of tests in POE:</b> <br> I found that the cleanest and easiest way to test is always accompanied by these following guidelines:</p><ul> <li>Always test a single <a href="http://search.cpan.org/perldoc?POE::Session">POE Session</a> at a time. Sometimes the sessions interact. You can mock sessions in order to work through that. Testing POE is difficult enough as it is without testing 10, 20 or 300 Sessions at a time. So do yourself a favor. Each time work on only one session. I separate my tests to folders according to the sessions I have. I have a folder for a Master Session, a Slave Session, a Worker session and so on.</li><li>Override the session you intend to test. This will allow you to change the session environment, its subroutines, events, alarms, and so on. It will keep the Kernel session-specific and make everything self-contained and a hell of a lot easier.</li><li>Preferably test events separately. This isn't always desired or necessary but I find it much more comfortable. I keep every event as a separate test file. The reason for this is the same as why I work on only one session at a time. I helps me test it without going insane with the multitude.</li><li>When testing an event, override and mock everything in its surrounding in order to test it. This is something the True Test Lords have known for a long while now. Creating a controlled environment is the best way to check something. Same goes here. You should mock and override every subroutine, attribute, event or anything else that comes in contact with the event you're testing. Think... Ebola!</li><li>Separate event tests with subroutine tests. All subroutines should be tested regardless of the POE Running test, in the regular way you test subroutines (or methods). Events will be tested separately in a different manner that requires running POE and seeing what happens.</li></ul><p> <b>Next post starts with types of tests!</b> </p> xsawyerx 2009-10-07T10:46:02+00:00 journal