<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-36345871</id><updated>2012-02-16T13:39:34.575-08:00</updated><category term='ironman'/><title type='text'>Perl Alchemy - notes of a former Catalyst programmer</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default?start-index=101&amp;max-results=100'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>139</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-36345871.post-2156579344289749283</id><published>2012-01-14T23:48:00.000-08:00</published><updated>2012-01-15T01:09:25.512-08:00</updated><title type='text'>Schlep</title><content type='html'>Schlep is tedious, unpleasant task. &amp;nbsp;&lt;a href="http://paulgraham.com/schlep.html%22"&gt;According to Paul Graham schlep is also what really defines a company&lt;/a&gt; - it is doing the tasks that are unpleasant and tedious for someone that they would pay you for.&lt;br /&gt;&lt;br /&gt;Narrowing this down to my own Perl web development work - the schlep for me was always getting the basic web app running with user registration, login pages, password reset mechanisms, etc. - in every new project that was the most repeatable, boring work. &amp;nbsp;I think everyone has the feeling that this does not need to be like that. &amp;nbsp;I've started thinking about what could be a solution to this and here are my first experiments about fixing it: &lt;a href="https://github.com/zby/Plack-Middleware-Auth-Form"&gt;Plack-Middleware-Auth-Form&lt;/a&gt;,&amp;nbsp;&lt;a href="https://github.com/zby/WebPrototypes-ResetPass"&gt;WebPrototypes::ResetPass&lt;/a&gt;, &lt;a href="https://github.com/zby/WebPrototypes-Registration"&gt;WebPrototypes::Registration&lt;/a&gt; (I might rename the first one to WebPrototypes as well). &amp;nbsp;The point is to solve it across the multiple web frameworks, templating languages and storage layers - so that it can survive moving from project to project.&lt;br /&gt;&lt;br /&gt;What is your schlep?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-2156579344289749283?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/2156579344289749283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=2156579344289749283' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2156579344289749283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2156579344289749283'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2012/01/schlep.html' title='Schlep'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-8393565161125011126</id><published>2011-12-10T13:20:00.001-08:00</published><updated>2011-12-10T13:35:15.229-08:00</updated><title type='text'>A kind of call by name</title><content type='html'>I often write code like this:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;$self-&amp;gt;create_user( username =&amp;gt; $username, email =&amp;gt; $email, pass_token =&amp;gt; $pass_token );&lt;/blockquote&gt;I wish I could get rid of the naming redundancy in this call:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;$self-&amp;gt;create_user( $username, $email, $pass_token );&lt;/blockquote&gt;(without changing 'create_user' of course).&lt;br /&gt;&lt;br /&gt;Probably some new syntax would be needed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-8393565161125011126?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/8393565161125011126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=8393565161125011126' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8393565161125011126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8393565161125011126'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/12/kind-of-call-by-name.html' title='A kind of call by name'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-703066386380546246</id><published>2011-11-18T23:42:00.001-08:00</published><updated>2011-11-21T01:46:53.115-08:00</updated><title type='text'>'use strict' and cargo cult programming</title><content type='html'>I've just read&amp;nbsp;&lt;a href="http://perl.plover.com/yak/12views/samples/notes.html#sl-31"&gt; mjd's confession "Why I Hate strict"&lt;/a&gt;,&amp;nbsp;it is from 2003 so he might have changed his views now, but there is nothing that would indicate that on this web page. &amp;nbsp;Anyway, his main argument that the usual advice to &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: x-small;"&gt;use strict&lt;/span&gt;&amp;nbsp;is automatic and mindless &amp;nbsp;and that it often does not really prevent the problems that people think it does. &amp;nbsp;In other words it is a&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Cargo_cult"&gt;cargo cult&lt;/a&gt;&amp;nbsp;programming to which he contrast programming with thinking and deep analysis of everything you do.&lt;br /&gt;&lt;br /&gt;I used to program without &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: x-small;"&gt;use strict; use warnings&lt;/span&gt;&amp;nbsp;but after exposure to the usual propaganda I switched and I found that the cost of mindlessly adding it is&amp;nbsp;negligible, the cases where I need &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: x-small;"&gt;no strict&lt;/span&gt;&amp;nbsp;are very rare, and there are many benefits of doing it, especially when working with old code. &amp;nbsp;This cult is rather effective in luring the cargo planes to land in my&amp;nbsp;atoll. &amp;nbsp;On the other hand I am all for deep analysis and checking your assumptions from time to time. &amp;nbsp;There are many valid points in Marc Lehman&amp;nbsp;&lt;a href="http://search.cpan.org/perldoc?common::sense"&gt;common::sense&lt;/a&gt;&amp;nbsp;and I would like to see them discussed. &amp;nbsp;While we are on the road to have &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: x-small;"&gt;use strict&lt;/span&gt; by default we might also try to make it better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-703066386380546246?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/703066386380546246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=703066386380546246' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/703066386380546246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/703066386380546246'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/11/use-strict-and-cargo-cult-programming.html' title='&apos;use strict&apos; and cargo cult programming'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3094980317057709332</id><published>2011-11-12T04:22:00.001-08:00</published><updated>2011-11-12T07:29:29.180-08:00</updated><title type='text'>$ primes for money</title><content type='html'>The thesis above sounds uncontroversial. &amp;nbsp;It is also rather uncontroversial that '$' is relatively frequently used when programming in Perl. &amp;nbsp;Now - what can be&amp;nbsp;&lt;a href="http://www.google.com/search?gcx=c&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&amp;amp;q=priming+for+money"&gt;the consequences of that&lt;/a&gt;?&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;Money has been said to change people's motivation (mainly for the better) and their behavior toward others (mainly for the worse). The results of nine experiments suggest that money brings about a self-sufficient orientation in which people prefer to be free of dependency and dependents. Reminders of money, relative to nonmoney reminders, led to reduced requests for help and reduced helpfulness toward others. Relative to participants primed with neutral concepts, participants primed with money preferred to play alone, work alone, and put more physical distance between themselves and a new acquaintance.&lt;/blockquote&gt;from &lt;a href="http://www.sciencemag.org/content/314/5802/1154.abstract"&gt;one of the first links in the query above&lt;/a&gt;. &amp;nbsp;Pretty sad - can that apply to the Perl community? Another link from that list,&amp;nbsp;&lt;a href="http://www.youtube.com/watch?feature=player_embedded&amp;amp;v=mW2SByfHpYg"&gt;an entertaining BBC video report&lt;/a&gt;&amp;nbsp;suggests also some other effects: hunger and pain insensitivity.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3094980317057709332?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3094980317057709332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3094980317057709332' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3094980317057709332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3094980317057709332'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/11/primes-for-money.html' title='$ primes for money'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-4573187674804750715</id><published>2011-11-07T10:21:00.000-08:00</published><updated>2011-11-08T03:07:06.716-08:00</updated><title type='text'>Thesis: simple - antythesis: easy - synthesis: ...</title><content type='html'>Rich Hickey's &lt;a href="http://www.infoq.com/presentations/Simple-Made-Easy"&gt;Simple Made Easy&lt;/a&gt; is a great talk, a must see, with lot's of insight, but together with that it also misrepresents what Agile is about.&amp;nbsp; Hickey's main point is that we should try to write simple software, because this is the only way to have reliable software, and he is right of course. &amp;nbsp; He notes that when you encounter a new bug and try to fix it - all the existing tests pass - so they will not help you in finding the cause of it.&amp;nbsp; You need to do the bug analysis on your own&amp;nbsp; and the complexity of your code is your enemy there.&amp;nbsp; He is also right when he talks about how &lt;i&gt;easy&lt;/i&gt;&amp;nbsp;means &lt;i&gt;familiar &lt;/i&gt;a not &lt;i&gt;simple&lt;/i&gt; and that it is a trap because it drives us away from the other (in small increments I would add).&amp;nbsp; He is insightful when he talks about things that are source of complexity.&amp;nbsp;&amp;nbsp; He is funny, but missing the point in his critique of Agile.&lt;br /&gt;&lt;br /&gt;The development sprints he attacks are not about doing the bulk of the work - they are about building a prototype on which we can test our assumptions.&amp;nbsp; Without the understanding that we get from these prototypes we could simplify as much as we want but it would not change the fact that our solution solves the wrong problem.&amp;nbsp; &lt;b&gt;&lt;/b&gt;Agile is not an enemy of simple, it puts a lot of weight to doing the &lt;i&gt;easy&lt;/i&gt; - but not because this is the goal - rather it uses &lt;i&gt;easy&lt;/i&gt; as a mean to get to the &lt;i&gt;correct&lt;/i&gt;. &lt;b&gt;Agile is the answer to the paradox that we don't know what we should make until we already have a prototype of that thing.&lt;/b&gt;&amp;nbsp; I wish more developers cared about &lt;i&gt;simple&lt;/i&gt; - but only after they know what is needed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-4573187674804750715?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/4573187674804750715/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=4573187674804750715' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4573187674804750715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4573187674804750715'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/11/thesis-simple-antythesis-easy-synthesis.html' title='Thesis: simple - antythesis: easy - synthesis: ...'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3758600653897366632</id><published>2011-11-01T10:23:00.000-07:00</published><updated>2011-11-01T10:23:24.213-07:00</updated><title type='text'>Notes on the Synthesis of Form</title><content type='html'>According to Wikipedia the origin of&amp;nbsp; &lt;a href="http://en.wikipedia.org/wiki/Design_pattern"&gt;Design Patterns&lt;/a&gt;&amp;nbsp;lays in the Pattern Language ideas by the unorthodox architect and philosopher &lt;a href="http://en.wikipedia.org/wiki/Christopher_Alexander"&gt;Christopher Alexander&lt;/a&gt;, but his earlier work also used to be widely read by computer scientists:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;Alexander's &lt;i&gt;&lt;a href="http://en.wikipedia.org/wiki/Notes_on_the_Synthesis_of_Form" title="Notes on the Synthesis of Form"&gt;Notes on the Synthesis of Form&lt;/a&gt;&lt;/i&gt; was required reading for researchers in computer science throughout the 1960s. It had an influence&lt;sup class="reference" id="cite_ref-naur_7-0"&gt;&lt;a href="http://en.wikipedia.org/wiki/Christopher_Alexander#cite_note-naur-7"&gt;[8]&lt;/a&gt;&lt;/sup&gt; in the 1960s and 1970s on programming language design, modular programming, object-oriented programming&lt;a href="http://www.blogger.com/goog_2090500000"&gt;, &lt;/a&gt;software engineering and other design methodologies. Alexander's mathematical concepts and orientation were similar to &lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Edsger_Dijkstra" title="Edsger Dijkstra"&gt;Edsger Dijkstra&lt;/a&gt;'s influential &lt;i&gt;A Discipline of Programming&lt;/i&gt;.&lt;sup class="reference" id="cite_ref-8"&gt;&lt;a href="http://en.wikipedia.org/wiki/Christopher_Alexander#cite_note-8"&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/blockquote&gt;The solution to the design problem that he proposes there does not look too attractive now, but his models, his metaphors, his insight into the design process - it's all still relevant and spot on.&amp;nbsp; I am surprised that the Agile movement does not quote "Notes" as one of their foundation texts.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3758600653897366632?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3758600653897366632/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3758600653897366632' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3758600653897366632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3758600653897366632'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/11/notes-on-synthesis-of-form.html' title='Notes on the Synthesis of Form'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-2197865476648857004</id><published>2011-10-15T05:07:00.000-07:00</published><updated>2011-10-15T05:09:36.822-07:00</updated><title type='text'>Concentration and Flow or Yet Another Dependency Injection Note</title><content type='html'>Imagine that you need to do some small home improvement or maintenance work and you have all the needed tools, in good quality, clean and well maintained with all cutting blades sharpened and no missing screwdriver heads. A nice feeling - isn't it?  When you start work like this you can concentrate on the task at hand instead of thinking where you can borrow that drill tool.&lt;br /&gt;&lt;br /&gt;Collaborators in an algorithm are like those tools, having them readily available lets you concentrate on the problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-2197865476648857004?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/2197865476648857004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=2197865476648857004' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2197865476648857004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2197865476648857004'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/10/concentration-and-flow-or-yet-another.html' title='Concentration and Flow or Yet Another Dependency Injection Note'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-4870227291412518296</id><published>2011-10-14T02:41:00.000-07:00</published><updated>2011-10-14T04:17:25.809-07:00</updated><title type='text'>Object oriented versus functional interface</title><content type='html'>I use &lt;a href="http://search.cpan.org/perldoc?DateTime::Format::W3CDTF"&gt;DateTime::Format::W3CDTF&lt;/a&gt; for parsing my dates:&lt;p&gt;&lt;code&gt;my $w3c = DateTime::Format::W3CDTF-&gt;new;&lt;br /&gt;my $dt = $w3c-&gt;parse_datetime( $date_string );&lt;br /&gt;&lt;/code&gt;&lt;p&gt;I wish it was:&lt;p&gt;&lt;code&gt;my $dt = DateTime::Format::W3CDTF-&gt;parse_datetime( $date_string );&lt;/code&gt;&lt;p&gt;and that the library created the parser on the fly as needed.   It's not only less typing - but also much simpler mental model.  This simpler model is sometimes too simple - for example if you parse a lot of dates then sparing the parser creation each time can make a difference.   &lt;p&gt;I think the optimal thing to do is provide two APIs - like &lt;a href="http://search.cpan.org/perldoc?JSON"&gt;JSON&lt;/a&gt; - a functional one:&lt;p&gt;&lt;code&gt; $perl_hash_or_arrayref  = decode_json $utf8_encoded_json_text;&lt;/code&gt;&lt;p&gt;and an object oriented one:&lt;p&gt;&lt;code&gt;$json = JSON-&gt;new-&gt;allow_nonref;&lt;br /&gt;$perl_scalar = $json-&gt;decode( $json_text );&lt;/code&gt;&lt;p&gt; for those that need that extra control.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-4870227291412518296?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/4870227291412518296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=4870227291412518296' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4870227291412518296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4870227291412518296'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/10/object-oriented-versus-functional.html' title='Object oriented versus functional interface'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-1004179752359958347</id><published>2011-10-03T05:21:00.000-07:00</published><updated>2011-10-03T05:21:30.763-07:00</updated><title type='text'>open expects filename as binary data encoded in the system characterset</title><content type='html'>I guess this is not a surprise to anyone who thought about how this is supposed to work, but for the sake of being systematic, here is the code:&lt;br /&gt;&lt;tt&gt;use strict; &lt;br /&gt;use warnings; &lt;br /&gt;use autodie;&lt;br /&gt;use HTML::Entities;&lt;br /&gt;use Encode;&lt;br /&gt;&lt;br /&gt;my $a = HTML::Entities::decode( '&amp;amp;ntilde;' );&lt;br /&gt;&lt;br /&gt;open(my $fh, '&gt;', $a );&lt;br /&gt;print $fh "Without encoding\n";&lt;br /&gt;close $fh;&lt;br /&gt;&lt;br /&gt;open(my $fh1, '&gt;', encode( 'UTF-8', $a ) );&lt;br /&gt;print $fh1 "With encoding\n";&lt;br /&gt;close $fh1&lt;br /&gt;&lt;/tt&gt;&lt;br&gt;And here is the result when run on an system with UTF8 locales:&lt;br /&gt;&lt;tt&gt;zby@zby:~/myopera/tmp$ ls&lt;br /&gt;?  a.pl  ñ&lt;br /&gt;zby@zby:~/myopera/tmp$ cat ñ&lt;br /&gt;With encoding&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;'a.pl' is the name of the script itself, the mark '?' hides the F1 hexadecimal code and that file contains 'Without encoding'.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-1004179752359958347?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/1004179752359958347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=1004179752359958347' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1004179752359958347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1004179752359958347'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/10/open-expects-filename-as-binary-data.html' title='open expects filename as binary data encoded in the system characterset'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-685658402873954483</id><published>2011-09-30T00:20:00.000-07:00</published><updated>2011-09-30T00:20:08.353-07:00</updated><title type='text'>Courriel::MMS</title><content type='html'>I think it is time to announce &lt;a href="https://github.com/operasoftware/Courriel--MMS"&gt;Courriel::MMS&lt;/a&gt; - it is an extension for the new &lt;a href="http://search.cpan.org/perldoc?Courriel"&gt;email handling library by Dave Rolsky&lt;/a&gt; for processing MMS messages forwarded as emails by the mobile operators.   This is still just a github link, no CPAN package yet, but it works in our production servers since Wednesday - so I bet on this code :)&lt;br /&gt;&lt;br /&gt;It is a bit heuristic - for example many operators send a subject like 'You have received an mms' - which is useless for us, so the library tries to find something else that would act as the subject we need.  For dealing with the various mobile operators, that each send a slightly different format of these emails, I used the Factory design pattern together with Module::Pluggable - this is a novel design for me so I wait for comments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-685658402873954483?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/685658402873954483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=685658402873954483' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/685658402873954483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/685658402873954483'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/09/courrielmms.html' title='Courriel::MMS'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-2598329008446511229</id><published>2011-09-20T08:29:00.000-07:00</published><updated>2011-09-23T12:32:39.276-07:00</updated><title type='text'>URI-&gt;path expects binary data</title><content type='html'>&lt;b&gt;Update:&lt;/b&gt; changed &lt;tt&gt;new&lt;/tt&gt; to &lt;tt&gt;path&lt;/tt&gt; - with &lt;tt&gt;new&lt;/tt&gt; it would be reasonable to require that the uri fed to the parser is already an ASCI string containing the already URI encoded url.&lt;br /&gt;Consider this code:&lt;br /&gt;&lt;tt&gt;use 5.010;&lt;br /&gt;use Encode 'encode';&lt;br /&gt;use URI;&lt;br /&gt;&lt;br /&gt;my $uri = URI-&gt;new( 'http://example.com/' );  &lt;br /&gt;say $uri-&gt;path( encode("UTF-8", "can\x{00B4}t-make-it-work" ) );&lt;br /&gt;say $uri-&gt;path( "can\x{00B4}t-make-it-work" );&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;The output (in perl 5.14.0) is:&lt;br /&gt;&lt;tt&gt;http://example.com/can%C2%B4t-make-it-work&lt;br /&gt;http://example.com/can%B4t-make-it-work&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;If your page is encoded in UTF8 - then the first one is correct: %C2%B4 is the URI encoded UTF8 encoding of &lt;a href="http://www.fileformat.info/info/unicode/char/00B4/index.htm"&gt;Unicode Character 'ACUTE ACCENT' (U+00B4)&lt;/a&gt;. If your page encoding is Latin1 - then the second one would be correct - but this is only by accident - in that case you should still use &lt;tt&gt;encode("iso-8859-1", ...)&lt;/tt&gt;.&lt;p&gt;There are probably many other string manipulating libs that should document if their input should be binary encoded data or decoded character strings.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-2598329008446511229?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/2598329008446511229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=2598329008446511229' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2598329008446511229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2598329008446511229'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/09/uri-new-expects-binary-data.html' title='URI-&gt;path expects binary data'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3794165946134486245</id><published>2011-09-01T05:57:00.000-07:00</published><updated>2011-09-01T05:57:07.748-07:00</updated><title type='text'>Names are special</title><content type='html'>At perl.com Tom Christiansen &lt;a href="http://www.perl.com/pub/2011/08/whats-wrong-with-sort-and-how-to-fix-it.html"&gt;talks about sorting names&lt;/a&gt;, among other things.  It appears surprisingly difficult to do properly with many special rules for each language.  By coincidence at programming.reddit.com just above a link to that article there is &lt;a href="http://www.w3.org/International/questions/qa-personal-names"&gt;Personal names around the world&lt;/a&gt;  - a link to a w3c article about even more complications with names.  At &lt;a href="http://philpapers.org/"&gt;PhilPapers&lt;/a&gt; we had to solve *somehow* a few of these - the result is &lt;a href="http://search.cpan.org/perldoc?Text::Names"&gt;Text::Names&lt;/a&gt;.  It is still rather limited: "While it tries to accommodate non-Western names, this module definitely works better with Western names, especially English-style names" - but there is already lots of logic embedded there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3794165946134486245?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3794165946134486245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3794165946134486245' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3794165946134486245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3794165946134486245'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/09/names-are-special.html' title='Names are special'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-429818072914006183</id><published>2011-08-28T15:46:00.001-07:00</published><updated>2011-08-28T22:48:04.954-07:00</updated><title type='text'>is_utf8 is useless - can we have is_character?</title><content type='html'>Consider this code:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$data_structure = utf8::is_utf8($json)&lt;br /&gt;   ? from_json($json)&lt;br /&gt;   : decode_json($json);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;taken, together with the &lt;code&gt;is_character&lt;/code&gt; suggestion, from otherwise very informative post: &lt;a href="http://blogs.perl.org/users/polettix/2011/08/quick-note-on-using-module-json.html"&gt;Quick note on using module JSON&lt;/a&gt;.  I have seen similar code in many places.  The idea is to check if the string you have is character data or a string of bytes and treat it appropriately.  Unfortunately &lt;code&gt;is_utf8&lt;/code&gt; does not do that check:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;use strict;&lt;br /&gt;use warnings;&lt;br /&gt;&lt;br /&gt;use utf8;&lt;br /&gt;use HTML::Entities;&lt;br /&gt;use JSON;&lt;br /&gt;&lt;br /&gt;my $a = HTML::Entities::decode( '&amp;amp;nbsp;' );&lt;br /&gt;my $json = qq{{ "a": "$a" }};&lt;br /&gt;print 'is_utf8: ' . ( utf8::is_utf8( $json ) ? 'yes' : 'no' ) . "\n";&lt;br /&gt;&lt;br /&gt;my $data_structure = utf8::is_utf8( $json )&lt;br /&gt;   ? from_json( $json )&lt;br /&gt;   : decode_json( $json );&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This fails (on my machine) with following output:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;is_utf8: no&lt;br /&gt;malformed UTF-8 character in JSON string, at character offset 8 (before "\x{8a0}" }") at a.pl line 12.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;If that still is a mystery try this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;use strict;&lt;br /&gt;use warnings;&lt;br /&gt;&lt;br /&gt;use HTML::Entities;&lt;br /&gt;use Devel::Peek;&lt;br /&gt;&lt;br /&gt;Dump( HTML::Entities::decode( '&amp;amp;nbsp;' ) );&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;the output (on my machine) is:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;SV = PV(0x24f2090) at 0x24f3de8&lt;br /&gt;  REFCNT = 1&lt;br /&gt;  FLAGS = (TEMP,POK,pPOK)&lt;br /&gt;  PV = 0x2501620 "\240"\0&lt;br /&gt;  CUR = 1&lt;br /&gt;  LEN = 16&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;this string is internally encoded as "\240" i.e. "\x{0a}" which is &lt;b&gt;Latin1&lt;/b&gt; encoding of non-breaking space.  It does not have the utf8 flag set - so the code above tries to treat it as UTF8 encoded stream of bytes and fails.&lt;br /&gt;&lt;br /&gt;I don't know if we can have &lt;code&gt;is_character&lt;/code&gt; easily - but the lack of introspection here is surely painful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-429818072914006183?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/429818072914006183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=429818072914006183' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/429818072914006183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/429818072914006183'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/08/isutf8-is-useless-can-we-have.html' title='is_utf8 is useless - can we have is_character?'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-2071136883081166101</id><published>2011-08-24T06:26:00.000-07:00</published><updated>2011-08-24T08:28:34.235-07:00</updated><title type='text'>CPAN, decoupling and Dependency Injection</title><content type='html'>Consider the code:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sub fetch&lt;br /&gt;{&lt;br /&gt;    my ($self, $uri) = @_;&lt;br /&gt;    my $ua           = LWP::UserAgent-&gt;new;&lt;br /&gt;    my $resp         = $ua-&gt;get( $uri );&lt;br /&gt;&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Yes - this is taken from &lt;a href="http://www.modernperlbooks.com/mt/2011/08/youre-already-using-dependency-injection.html"&gt;a post by chromatic&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now imagine that this is code from a CPAN module you installed and that some security concerns require you to replace LWP::UserAgent with LWPx::ParanoidAgent there.  Bad luck - you'll probably need to subclass it, override that whole &lt;code&gt;fetch&lt;/code&gt; method and pray that it will not change too much with every new release of the original module.&lt;br /&gt;&lt;br /&gt;This is really why I am drumming this Dependency Injection drum over and over again - code that uses it is more reusable, more universal:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;use Moose;&lt;br /&gt;has 'ua', is =&gt; 'ro', default =&gt; sub { LWP::UserAgent-&gt;new };&lt;br /&gt;&lt;br /&gt;sub fetch&lt;br /&gt;{&lt;br /&gt;    my ($self, $uri) = @_;&lt;br /&gt;    my $ua           = $self-&gt;ua;&lt;br /&gt;    my $resp         = $ua-&gt;get( $uri );&lt;br /&gt;&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now you would not have any problem with providing a LWPx::ParanoidAgent object for the fetch method to use.&lt;br /&gt;&lt;br /&gt;By the way, with classical DI you'd move that &lt;code&gt;LWP::UserAgent-&gt;new&lt;/code&gt; completely out from the class, here it stays as a 'default' that can be overridden from outside if you need.  The problem with classical DI is that you need to have a place where to move that initialization code - here it is sidestepped for the 'normal' usage and you need to worry about it only in the cases where you really need to.  Java probably does not have this 'default' mechanism.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-2071136883081166101?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/2071136883081166101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=2071136883081166101' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2071136883081166101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2071136883081166101'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/08/cpan-decoupling-and-dependency.html' title='CPAN, decoupling and Dependency Injection'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-7717584719797016207</id><published>2011-08-18T12:22:00.000-07:00</published><updated>2011-08-18T12:53:31.706-07:00</updated><title type='text'>Dependency Injeciton - the cooking metaphor</title><content type='html'>Let's take a &lt;a href="http://homecooking.about.com/od/cakerecipes/r/blc13.htm"&gt;typical recipe&lt;/a&gt;.  It first describes the goal - and then it goes:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;b&gt;Ingredients:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;2-1/4 cups sifted cake flour&lt;br /&gt;&lt;li&gt;2 teaspoons baking powder&lt;br /&gt;&lt;li&gt;1/2 teaspoon salt&lt;br /&gt;&lt;li&gt;1/2 pound (2 sticks) sweet butter, room temperature&lt;br /&gt;...&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;Preparation:&lt;/b&gt;&lt;br /&gt;Preheat the oven to 350 degrees Fahrenheit. Butter and line two 8 x 3-inch baking pans or one 12 x 3-inch pan with parchment.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;It is not:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Preheat the oven to 350 degrees Fahrenheit.  Find a cow and milk her, wait until ...&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;neither it is:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Preheat the oven to 350 degrees Fahrenheit.  Take your credit card and go to the grocery around the corner ...&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Dependency injection is about writing your programs in a very similar manner - you first declare the collaborators and then go on with using them.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-7717584719797016207?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/7717584719797016207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=7717584719797016207' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/7717584719797016207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/7717584719797016207'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/08/dependency-injeciton-cooking-metaphor.html' title='Dependency Injeciton - the cooking metaphor'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-4324667188238717053</id><published>2011-08-11T06:21:00.000-07:00</published><updated>2011-08-12T01:16:12.135-07:00</updated><title type='text'>So what is Dependency Injection again?</title><content type='html'>The definition I like the most is that DI is simply about separating object creation from business logic.  Object creation - &lt;a href="http://misko.hevery.com/2008/07/08/how-to-think-about-the-new-operator/"&gt;wiring the application&lt;/a&gt; - is a special type of code, different from the rest and it is useful to keep it separated.  &lt;a href="http://perlalchemy.blogspot.com/2011/01/dependency-injection-or-removing.html"&gt;This is similar to how we remove hardcoded magic constants from our code into config files&lt;/a&gt;, it can be thought as a Object Oriented extension of that practice.  We remove magic constants because we need to change them more frequently than the rest of the code. We do DI because we need to change the object wiring much more frequently than we change business logic and in particular we need to change it in the tests - without that unit tests would not be possible.   But it is also different - because the object wiring code is much more complex than configuration files.&lt;br /&gt;&lt;br /&gt;But this is not all - DI is also about keeping all object collaborators in it's attributes instead of reaching out for global objects (or signletons which are globals in disguise or class attributes).  It thus improves object's encapsulation, makes them more self-reliant and testable.  Or maybe this part is not DI - but simply writing Object Oriented code?&lt;br /&gt;&lt;br /&gt;On the other hand, the separated out object factories are hard to test because they depend on all the objects classes they create and you want to keep them as small and simple as possible.  How many such factories you need? If we have something that has a http request object as attribute - then we cannot build it until the http request arrives from the user. If we keep all collaborators in objects attributes - then we cannot build them until we have all information needed to build all these collaborators first.    We thus need one factory per scope.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-4324667188238717053?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/4324667188238717053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=4324667188238717053' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4324667188238717053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4324667188238717053'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/08/so-what-is-dependency-injection-again.html' title='So what is Dependency Injection again?'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3425504626160769066</id><published>2011-08-02T05:33:00.000-07:00</published><updated>2011-08-02T06:17:54.824-07:00</updated><title type='text'>Subclassing applications</title><content type='html'>Subclassing is a great tool for making small changes to a piece of code to fit it to new requirements.  It is as easy as copying code - but it still keeps the new constructs synchronized with later changes to the original. There are problems with inheritance hierarchies - but you need to have a 'hierarchy', not just two classes, to get there.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I imagine that it would be perfect for extended configuration of applications - including web applications.  Wouldn't it be great if you could run a slightly changed version of you main web app by making it's code available from PERL5LIB and then subclassing it to change the colors used, add some minor new features and remove some pages for and affiliated site?  Or if you could install a blog engine from CPAN, and then subclass it to add new and override old features?  This could even make distribution of CPANized applications more popular.  &lt;br /&gt;&lt;br /&gt;This is one of the things I am experimenting with at &lt;a href="https://github.com/zby/Nblog"&gt;Nblog&lt;/a&gt; (see also the screencast: &lt;a href="http://warszawa.pm.org/WebNanoInheritance.mpeg"&gt;Experiments with inheritance in WebNano based applications&lt;/a&gt;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3425504626160769066?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3425504626160769066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3425504626160769066' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3425504626160769066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3425504626160769066'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/08/subclassing-applications.html' title='Subclassing applications'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6441439669070528672</id><published>2011-07-25T01:27:00.000-07:00</published><updated>2011-07-25T01:32:55.333-07:00</updated><title type='text'>Dependency Injection - Introduction - my talk for YAPC::Europe 2011</title><content type='html'>My talk was accepted and now I published the &lt;a href="http://warszawa.pm.org/DI_perl.odp"&gt;slides&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6441439669070528672?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6441439669070528672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6441439669070528672' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6441439669070528672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6441439669070528672'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/07/dependency-injection-introduction-my.html' title='Dependency Injection - Introduction - my talk for YAPC::Europe 2011'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-2082977585094166944</id><published>2011-06-27T07:26:00.000-07:00</published><updated>2011-06-27T08:26:35.420-07:00</updated><title type='text'>Callbacks versus the Template Method pattern</title><content type='html'>Let's say you have an object oriented html form validation library and, beside all the default checks (like non-empty or is_number etc.), you want the users of your library to add their own checks coded in the native programming language of your library.  You have two simple ways to do that - you can let the form object contain a callback to be used for the check or you can use the &lt;a href="http://en.wikipedia.org/wiki/Template_method_pattern"&gt;Template Method&lt;/a&gt; pattern and let programmers subclass your form (or maybe individual field) class and implement their own 'check' method.  Both solutions have their own pros and cons but I've never seen a comprehensive comparison of them.  &lt;br /&gt;&lt;br /&gt;What do you think about them?  It seems that some programmers groups prefer one solution over the other (it's hard not to notice how callbacks are popular in the Plack related stuff).  Callbacks are simpler, you don't need additional classes there, they don't complicate the program structure, but they are also more constrained.  Template Methods are more structural.  You can make them call other template methods and make that whole thing fine grained - that is harder with callbacks.  In FormHandler I wanted to be able to stack the many generic checks together into lists - but such lists are not very reusable, you cannot override parts of it like you could if they were named methods.  The point is that this additional class is another indirection layer and as we know that all programming problems are solvable with in this way :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-2082977585094166944?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/2082977585094166944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=2082977585094166944' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2082977585094166944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2082977585094166944'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/06/callbacks-versus-template-method.html' title='Callbacks versus the Template Method pattern'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3876855757270616879</id><published>2011-05-28T00:28:00.000-07:00</published><updated>2011-07-04T07:23:02.471-07:00</updated><title type='text'>The Bitcoin protocol - a highlevel explanation</title><content type='html'>&lt;a href="http://www.bitcoin.org/"&gt;Bitcoin&lt;/a&gt; is a peer to peer financial protocol.  There is no central authority that guarantees that the operations are valid, how can this work?  How can you trust strangers with your money?  Let's say you are selling something for bitcoins - you receive the amount quoted - how can you verify that the transaction was valid?  You need to check three things:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;That it was indeed the owner of the sender account that created the transaction.&lt;br /&gt;&lt;li&gt;That the sender received the BTCs he is now sending.&lt;br /&gt;&lt;li&gt;That he has not transfered these BTCs already somewhere else (double spending).&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;The first check is easy - all transactions are signed.  For the second you need to know another transaction that transfers the money to the senders account.  Of course now you'll need to verify the other transaction as well - and then, in a recursive fashion, all the others leading to the one that generated the bitcoins (more about generating later).  The sender could send you this chain of signed transactions - but in fact he does not need to do that because all the transactions are public.&lt;br /&gt;&lt;br /&gt;The third check is more tricky - for this you need to always know which transaction was first and which one is second and then possibly reject the second one if it is double spending.  This would be easy with a central authority that would timestamp all transactions and log them somehow - but it is very hard to do in a p2p system.  In bitcoin there is also a global &lt;a href="http://blockexplorer.com/"&gt;log of all transactions&lt;/a&gt; - it is called block chain (for it's technical representation).  The trick is that to add a valid record to that log you need to solve a hard computational problem.  You practically have no chances to do that singlehandedly and you need the other nodes in the network to help you. The sender broadcast his will to transfer money to the whole network and then wait until someone from this network solves the problem and correctly saves the transaction to the global log.  This is like going to the notary to make sure that all formalities are met.  After the transaction is saved to the log it is very hard to undo that - because you'd need to solve this hard problem again - and without a conspiracy between a significant part of the peers this would be impossible.&lt;br /&gt;&lt;br /&gt;To be more precise transactions are not logged individually - but rather in batches called blocks. Such a set of transactions is written to the log in one sweep.  This is important for efficiency - but not only.&lt;br /&gt;&lt;br /&gt;All of this happens in a distributed, asynchronous manner.  This means that it is possible that two nodes will write two new blocks to the transaction log in parallel and we'll get two different and valid versions of the log.  What would happen then is that when a next block is written down to one version of the log it will take over all of the transactions from the block in the alternative log version, so they are not lost.  But it is possible that the alternative logs contain two conflicting transactions (double spending) - then only one of them will be eventually saved.  This showcases one important thing - having the transaction written to the log does not yet guarantee that it will stay there, because it can happen that there exists an alternative, valid log version and that eventually this other one will be the one that is continued by the system.  But if you wait until another block is written to the log after the one that you are checking - then you are much more safe.  This is the most complex part of the protocol - but the general rule is that the more blocks are written to the log after your - the more safe you are, and the safety grows exponentially.&lt;br /&gt;&lt;br /&gt;Now - why so many nodes in the network would spend their time trying to save a new transaction block to the log?  This is because they are paid if they succeed. In each new block saved to the log there can be one transaction that generates a specific amount of BTCs (now it is 50 - but it will be less in the future). This is they way new bitcoins are generated.&lt;br /&gt;&lt;br /&gt;Another question is how the bitcoin project can maintain that the transactions are anonymous when they are all public?  The answer is that what is public is the addresses of the sender and the receiver but not who owns these addresses.  It is easy to create new addresses.  You can use a new one for every incoming transaction and you can also make transfers between your own accounts to hide the tracks.  Maybe it is not total privacy - but it is still better then with current money transfers where the banks know everything.&lt;br /&gt;&lt;br /&gt;This introduction leaves out lots of technical details - but I hope that it explains the protocol enough to convince readers that it can work :)  For more details have a look at the &lt;a href="http://www.bitcoin.org/bitcoin.pdf"&gt;original bitcoin paper&lt;/a&gt; and the &lt;a href="https://en.bitcoin.it/wiki/Protocol_specification"&gt;bitcoin wiki&lt;/a&gt; (just remember that what I call transaction log here is called block chain there).&lt;br /&gt;&lt;br /&gt;By the way - I've heard bitcoin makes internet tipping in fashion again - so  113uhu2LrJp8gXGDrDLLDqmFGxnC2e3suB is one of my addresses.  The interesting twist to that is that the donations are public - you can view the current ballance at &lt;a href="http://blockexplorer.com/address/113uhu2LrJp8gXGDrDLLDqmFGxnC2e3suB"&gt;blockexplorer&lt;/a&gt;.  I've already got some tips - thanks :)   Consider this an experiment in micropayments for blog financing.&lt;br /&gt;&lt;br /&gt;Update: A critical analysis of the decentralization of the bitcoin protocol: http://www.links.org/?p=1164&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3876855757270616879?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3876855757270616879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3876855757270616879' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3876855757270616879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3876855757270616879'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/05/bitcoin-protocol-highlevel-explanation.html' title='The Bitcoin protocol - a highlevel explanation'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-9069872940699561662</id><published>2011-05-15T00:45:00.000-07:00</published><updated>2011-05-15T00:59:49.285-07:00</updated><title type='text'>Synthetic attributes</title><content type='html'>&lt;a href="http://www.modernperlbooks.com/mt/2011/05/decoupling-testability-and-synthetic-attributes.html"&gt;chromatic writes about synthetic attributes&lt;/a&gt;.  I wonder why this is not more widely used - it's such a simple technique.  I've been using it since I discovered Moose and all the time in the back of my head I had this thought: Why people don't use this more widely?  It is so obvious solution to the testing problems.  Maybe they know something that I don't?  But maybe it is just the matter of some guru (like chromatic :) writing about this technique?&lt;br /&gt;&lt;br /&gt;PS. Sorry I'll not explain what &lt;em&gt;synthetic attributes&lt;/em&gt; mean - this post is only a comment.  I cannot currently comment at chromatic's blog.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-9069872940699561662?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/9069872940699561662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=9069872940699561662' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/9069872940699561662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/9069872940699561662'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/05/synthetic-attributes.html' title='Synthetic attributes'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-656402012046816136</id><published>2011-04-12T05:54:00.000-07:00</published><updated>2011-04-12T06:35:53.881-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>git push and other copy commands</title><content type='html'>The usual pattern of a copy command:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;copy source destination&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The pattern of git &lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git-push.html"&gt;push&lt;/a&gt; command&lt;br /&gt;&lt;code&gt;&lt;br /&gt;push destination source:destination&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;the first destination is the destination repository - the second is the branch (and 'source' is the source branch).  I must have skimmed the linked manual dozens of times over many years.  There was something that just did not make sense and I imagined that I would have to read some book or something to eventually understand the magic 'ref specs'. It never dawned on me that it was that simple.  &lt;br /&gt;&lt;br /&gt;The additional difficulty is that the destination repository is usually shortened to 'origin' (because it was the origin for the clone command).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-656402012046816136?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/656402012046816136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=656402012046816136' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/656402012046816136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/656402012046816136'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/04/git-push-and-other-copy-commands.html' title='git push and other copy commands'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-7178415077466739501</id><published>2011-03-26T06:06:00.000-07:00</published><updated>2011-03-28T03:44:46.325-07:00</updated><title type='text'>Drupal like architecture</title><content type='html'>The Drupal subject &lt;a href="http://blogs.perl.org/users/leo_lapworth/2011/02/portable-plugin-apps.html"&gt;reappears&lt;/a&gt; in the Perl blogsphere &lt;a href="https://github.com/robinsmidsrod/unnamed-perl-cms-project"&gt; regularly&lt;/a&gt;.  In my opinion there are three key architectural choices for 'portable plugin apps'.  First, obviously, the plugins needs to be highly independent.  Second they need to be controlled by pages - that is the page decide what plugins to use.  To meet the independence requirement, in the Plack world, the obvious choice for the plugis is that they are simply PSGI apps that in body return a page fragment.  This will make it easy to plugin existing wikis and blogs - you just need to remove the header and footer templates and voila you have a plugin instead of a standalone app.  You can also use all the Plack infrastructure, for example the &lt;a href="http://search.cpan.org/dist/Plack-Client/lib/Plack/Client.pm"&gt;Plack::Client&lt;/a&gt; if you ever care about scaling your application.&lt;br /&gt;&lt;br /&gt;There is one thing that I forgot in the first version of this post - Javascript and CSS.  Applications are rarely pure HTML these days - we'll need also some way to gather all the js and css files that the plugins use and link them in the main page.  At the main page side this is nothing special - it is not unusual that applications concatenate many Javascript libraries into one file automatically - so this is already well explored.  The complication arises from the requirement to pass something more structured then just a HTML fragment in the Plack response from the plugins.&lt;br /&gt;&lt;br /&gt;More interesting is the other key choice - how the plugins are supposed to be plugged in.  That is how page handlers will choose what plugin to use and what data pass there.  As much as I hate the 'program in XML' approach to language syntax - the obvious established standard here is &lt;a href="http://www.akamai.com/html/support/esi.html"&gt;ESI&lt;/a&gt;.  Maybe we could even steal the semantics and replace the syntax with something saner?  Plack based ESI implementation was submitted as an &lt;a href="http://epo.means.no/gsoc2011/ideas"&gt;example GSOC idea&lt;/a&gt; - I really hope some student will pick it up.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt; Added js/css handling consideration (thanks for cezio comment below).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-7178415077466739501?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/7178415077466739501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=7178415077466739501' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/7178415077466739501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/7178415077466739501'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/03/drupal-like-architecture.html' title='Drupal like architecture'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-2559961528499349884</id><published>2011-03-19T03:49:00.000-07:00</published><updated>2011-03-20T13:22:24.455-07:00</updated><title type='text'>App initialization and web frameworks</title><content type='html'>Building the application object and its components has nothing to do with serving web pages.  The database model setup is exactly the same if you do it for a web application or for your cron utilities and it should also remain the same if you one day decide to make a desktop version of your app.  There is no reason that this initialization is a part of web frameworks other then we don't currently have a good standalone application builders.  Now every web framework reinvents the wheel and writes one from scratch.  Fortunately (in the Perl universe) there are now multiple &lt;a href="http://sites.google.com/site/configloader/"&gt;efforts&lt;/a&gt; to create the &lt;a href="http://blogs.perl.org/users/vyacheslav_matjukhin/2010/12/morpheus---ultimate-configuration-engine.html"&gt;ultimate&lt;/a&gt; configuration engine.  There is just one step from a config reader to an application configurator.&lt;br /&gt;&lt;br /&gt;As I have already &lt;a href="http://blog.urth.org/2011/01/config-versus-code.html#comment-25005"&gt;commented elsewhere&lt;/a&gt;, I think the ideal for big projects would be a simple config file using simplified syntax that could be changed by the admins plus a Dependency Injection container that would build all the application components from the primitive values provided by this config.  This DI container would be a second level configuration - still simple code but touchable only by programmers.  For &lt;a href="https://github.com/zby/WebNano/blob/master/lib/WebNano.pm"&gt;small applications&lt;/a&gt; I was quite happy with &lt;a href="http://search.cpan.org/dist/MooseX-SimpleConfig/"&gt;MooseX::SimpleConfig&lt;/a&gt; and Moose type coercions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-2559961528499349884?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/2559961528499349884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=2559961528499349884' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2559961528499349884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2559961528499349884'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/03/app-initialization-and-web-frameworks.html' title='App initialization and web frameworks'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-938245016554097981</id><published>2011-03-15T14:21:00.000-07:00</published><updated>2011-03-16T07:29:11.393-07:00</updated><title type='text'>Reblessing objects</title><content type='html'>Yesterday I've read the example from &lt;a href="http://martinfowler.com/books.html#refactoring"&gt;Refactoring&lt;/a&gt; transcripted &lt;a href="http://jczeus.com/refac_perl.html"&gt;into Perl&lt;/a&gt;.  Nice work (I am not sure about the legal status of this - but I am sure that it is a great advert for the original book). The last refactoring there starts with:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;We have several types of movie that have different ways of answering the same question. This sounds like a job for subclasses. We can have three subclasses of movie, each of which can have its own version of charge (Figure 1.14).&lt;br /&gt;&lt;br /&gt;This allows me to replace the switch statement by using polymorphism. Sadly it has one slight flaw - it doesn't work. A movie can change its classification during its lifetime. An object cannot change its class during its lifetime. &lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;It then goes on to show how the State Pattern can solve the problem thus stated.  I am not so sure about this argumentation - typically the movie data would be stored in a database and the object would be created just for the one transaction - I think it is reasonable to assume that the movie does not change it's classification during the transaction.  But OK - all this is just to show how the State Pattern solves the problem even if in this case the problem itself would not be real - for sure there are cases where it would.  &lt;br /&gt;&lt;br /&gt;Then it got me thinking - well in Perl you can change the class of an object during it's lifetime.  I've even seen it done, I don't quite remember where.  In general it is considered to be nasty - but is it always?  In real life it is normal that things change - a caterpillar becomes a butterfly, a child becomes an adult.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-938245016554097981?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/938245016554097981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=938245016554097981' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/938245016554097981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/938245016554097981'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/03/reblessing-objects.html' title='Reblessing objects'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6590774318046307870</id><published>2011-03-14T13:49:00.000-07:00</published><updated>2011-03-14T14:21:40.768-07:00</updated><title type='text'>Spark::Form</title><content type='html'>I remember when when James was starting his project - his basic ideas were exactly the same as our HTML::FormHandler design.  Unfortunately he learned about FormHandler after he had started coding - no way to talk him to change his plans and join FormHandler.  Reinventing the wheel - but what I can decipher from &lt;a href="http://jameslaver.com/presentations/spark/"&gt;his latest presentation&lt;/a&gt; - is quite interesting.  Model integration - which is a major source of the complexity he criticized in HFH - is still lacking but the validation method is intriguing.  Maybe cross-pollination will be possible?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6590774318046307870?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6590774318046307870/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6590774318046307870' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6590774318046307870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6590774318046307870'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/03/sparkform.html' title='Spark::Form'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-7057580311072929782</id><published>2011-03-01T10:15:00.000-08:00</published><updated>2011-03-01T10:44:38.923-08:00</updated><title type='text'>Plack::Middleware::Auth::Form on CPAN</title><content type='html'>I've got a bit impatient in waiting for feedback and this week I &lt;a href="http://search.cpan.org/dist/Plack-Middleware-Auth-Form/lib/Plack/Middleware/Auth/Form.pm"&gt;uploaded Plack::Middleware::Auth::Form to CPAN&lt;/a&gt;.  This does not mean it is entirely finished - but at least it should be easier to install.&lt;br /&gt;&lt;br /&gt;Plack::Middleware::Auth::Form has similar functionality as &lt;a href="http://search.cpan.org/dist/CatalystX-SimpleLogin/lib/CatalystX/SimpleLogin.pm"&gt;CatalystX::SimpleLogin&lt;/a&gt;, but since it is at the Plack level it can be reused by any Plack based framework.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-7057580311072929782?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/7057580311072929782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=7057580311072929782' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/7057580311072929782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/7057580311072929782'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/03/plackmiddlewareauthform-on-cpan.html' title='Plack::Middleware::Auth::Form on CPAN'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6840463835733940074</id><published>2011-02-19T09:56:00.000-08:00</published><updated>2011-02-19T10:16:08.952-08:00</updated><title type='text'>Plack::Middleware::Auth::Form - like CatalystX::SimpleLogin but at Plack level.</title><content type='html'>I've just published a first version to github: &lt;a href="https://github.com/zby/Plack-Middleware-Auth-Form"&gt;zby / Plack-Middleware-Auth-Form&lt;/a&gt;.  The &lt;code&gt;authenticator&lt;/code&gt; parameter (and it's initialization) is copied from &lt;a href="http://search.cpan.org/dist/Plack/lib/Plack/Middleware/Auth/Basic.pm"&gt;Plack::Middleware::Auth::Basic&lt;/a&gt; - this is a much simpler interface then &lt;a href="http://search.cpan.org/dist/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication.pm"&gt;Catalyst::Plugin::Authentication&lt;/a&gt; - but I think it can be enough.&lt;br /&gt;&lt;br /&gt;The redirects from and to the login page are modeled after &lt;a href="http://search.cpan.org/dist/CatalystX-SimpleLogin/lib/CatalystX/SimpleLogin.pm"&gt;CatalystX::SimpleLogin&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;t/app.psgi&lt;/code&gt; is the only example so far, but I plan to use it in Nblog.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6840463835733940074?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6840463835733940074/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6840463835733940074' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6840463835733940074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6840463835733940074'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/02/plackmiddlewareauthform-like.html' title='Plack::Middleware::Auth::Form - like CatalystX::SimpleLogin but at Plack level.'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6771455716596979443</id><published>2011-02-10T12:11:00.002-08:00</published><updated>2011-02-10T14:33:16.113-08:00</updated><title type='text'>Is Newables/Injectables a fundamental distinction?</title><content type='html'>In &lt;a href="http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/"&gt;To “new” or not to “new”…&lt;/a&gt; Misko Hevery advices us to divide object classes into Injectables and Newables.  Newables are objects that cannot be injected with DI frameworks (that is by one type of DI frameworks), Injectables are those that can.  The point is to build Injectables only from other Injectables and Newables only from other Newables.  To complete this recursive definition the simple Newables are defined as objects that have attributes of only primitive types.  It is not so clear what are the atomic Injectables.  I guess technically this needs be classes with parameter-less constructors.  The examples given suggest things that you get from the OS or external libraries like an audio device or socket, or database connection.  Of course sockets are not really parameterless - you need to pass the port number as an argument to the external libraries that create one, neither are audio devices if you have more then one attached to your computer - so this will only work if we assume that the given program works with just one port number or only with '/dev/audio'.  What if you wanted to test it on another port?  And what if you wanted to have and object containing an array of available sockets - you could not pass the number of the sockets in its constructor, because this would spoil its Injectableness.  Parameter-less constructors are only hiding globals.&lt;br /&gt;&lt;br /&gt;This distinction between Newables and Injectables proves to be rather constraining - it would be much cleaner if every class (and indeed also primitive types) were Injectable.  Fortunately it is only an artefact of the DI framework chosen - there are DI frameworks that can inject any value, because they find them by name not by type.  In these frameworks all classes are Injectables - but it might still be useful to keep the name of Newables for objects that can be build internally without calling any external libraries.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6771455716596979443?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6771455716596979443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6771455716596979443' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6771455716596979443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6771455716596979443'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/02/are-newablesinjectables-fundamental_7105.html' title='Is Newables/Injectables a fundamental distinction?'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-5259580406338141089</id><published>2011-01-30T08:24:00.000-08:00</published><updated>2011-01-31T10:34:47.421-08:00</updated><title type='text'>Returning to current page after login</title><content type='html'>This is one of the must have conveniences of a modern web-site: if a logged out user encounters a page that requires a login then - after logging in the user goes directly to that original page (instead of staying on the login page or going to some other predefined page).  Here is a quick list of possible high-level solutions - anything missing?  What is your choice?&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;1. No redirect&lt;/h2&gt;&lt;br /&gt;Either you have the login form on every page (a small one) - or you can display the login form instead of the page text if the login is required.  You need more then a small box to fit in all the currently broadly used options like OpenId or logging in via Facebook - so for a universal solution you need a full page.  Let's focus on displaying the login form on a page requiring authentication instead of that page content.  This is a very simple solution - would it break any of the HTTP protocol rules?  But then wouldn't displaying the error message saying 'Login required' break the same rule?&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;2. Passing the current url in the link to the login form&lt;/h2&gt;&lt;br /&gt;The minus of this solution is the ugly url of the login page.  I also read somewhere that in some implementations there is a security problem - but I cannot find now any reference about it (it was something about crafting the uri param in a way that resulted in two http requests when the redirection was done).&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;3. Saving the current url in the session&lt;/h2&gt;&lt;br /&gt;Additionally to all the problems with sessions (and for example multiple tabs open to the site), there is a slight efficiency disadvantage if we do that for each link to the login page, because the session then needs to be saved every time.  If the session is save to the database I imagine that this could have a slight impact.  &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;4. Using the Referer HTTP header&lt;/h2&gt;&lt;br /&gt;This would also be quite simple - but can we rely on it?  Additionally it would also require passing that url from that header back to the form for the case when the first login attempt fails.  This can be done with hidden field - and since everyone uses POST for the login form method this would not spoil the login page url (or it can also be done with a session - but this time the session would be saved only in the case of a failed login).&lt;br /&gt;&lt;br /&gt;This would only work if the user followed a link from the current page to the login page (presumably displayed together with the authentication required error message).  But actually it is better to automate that step and:&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;5. Redirecting both to the login page and from it&lt;/h2&gt;&lt;br /&gt;This still requires saving the current page in the url (as in 2) or in the session (as in 3) - but without saving current url in the session at every page containing a link to the login page.  It can also be combined with 4 if additionally to this mechanism we want to have have links to the login page that would lead the user back to the original page.  From the user perspective this is as convenient as 1 but might be a bit more clean from the technology perspective (see Dave's comment below - although is 303 more correct here?). Anyway - this is the solution used by &lt;a href="http://search.cpan.org/dist/CatalystX-SimpleLogin/"&gt;CatalystX::SimpleLogin&lt;/a&gt; (and Catalyst::ActionRole::NeedsLogin).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Updates:&lt;/b&gt; Added 5.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-5259580406338141089?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/5259580406338141089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=5259580406338141089' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/5259580406338141089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/5259580406338141089'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/01/returning-to-current-page-after-login.html' title='Returning to current page after login'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-5877905746607859213</id><published>2011-01-10T00:48:00.000-08:00</published><updated>2011-01-10T06:13:25.905-08:00</updated><title type='text'>Is $ responsible for the 'ugliness' of Perl code?</title><content type='html'>We cannot hide it that Perl code is littered with the $ characters and, compared to the original well rounded Latin letters, that went through the thousands of years of tweaking to please the human eye, compared to them, $ is just an ugly hack.  Unfortunately this is what people see when they first look at Perl code - lots of $ signs (by the way @ looks a bit better - maybe we should use more arrays?) - and this is how unconsciously they form the first impression about our language.  This is not fair, this is so superficial - but the way the human mind works dictates that this first impression colours every information about Perl that comes later.  People don't like to change their minds, and they always will find something to support what they thought initially, even if, or maybe the more so when, that initial thought was just an unconscious impression.&lt;br /&gt;&lt;br /&gt;What can we do then?  Changing the typeface of $ in the most popular web and editor fonts does not seem like a practical solution, but maybe if we show the sheer shallowness of judging the language by the shape of the typeface of some used character - maybe this would have some impact?&lt;br /&gt;&lt;br /&gt;Update: Bear in mind that I don't advocate to get rid of $ in Perl - I find it very useful.  The point is that the type face ugliness of $ can project a shadow on the whole language completely independently from it's usefulness as language construct.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-5877905746607859213?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/5877905746607859213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=5877905746607859213' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/5877905746607859213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/5877905746607859213'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/01/is-responsible-for-ugliness-of-perl.html' title='Is $ responsible for the &apos;ugliness&apos; of Perl code?'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-1060930995947672853</id><published>2011-01-06T22:18:00.000-08:00</published><updated>2011-01-06T23:40:06.432-08:00</updated><title type='text'>Dependency Injection - some updates</title><content type='html'>I finally found a succinct and clear definition of Dependency Injection:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Dependency injection means giving an object its instance variables instead of letting it create them.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;based on answers to &lt;a href="http://stackoverflow.com/questions/130794/what-is-dependency-injection"&gt;What is dependency injection?&lt;/a&gt; on Stackoverflow.  There are some variations on how you do that - you can pass the instance variables in the call to the object creator (the &lt;code&gt;new&lt;/code&gt; method) or you can use a &lt;code&gt;setter&lt;/code&gt; to pass it to the object after it is created.  This is exactly what I was thinking.  &lt;em&gt;Inversion of Control&lt;/em&gt; here happens only if you use a framework that takes over the object creation - but this is not required for the practice of DI.  The name does not fit too well to its definition - but it is probably too late to change it.&lt;br /&gt;&lt;br /&gt;Reasons to do DI:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;The most immediate reason is that it makes it easy to use mockups (or even &lt;em&gt;undef&lt;/em&gt;'s or &lt;em&gt;Nulls&lt;/em&gt;) for the dependencies in tests.  But this is is just a concrete example of the more general reasons that follow.&lt;br /&gt;&lt;li&gt;To change the coupling between the main class and the dependency from &lt;em&gt;control coupling&lt;/em&gt; to &lt;em&gt;data-structured coupling&lt;/em&gt; (&lt;a href="http://en.wikipedia.org/wiki/Coupling_(computer_programming)#Types_of_coupling"&gt;Types of coupling&lt;/a&gt; in wikipedia).  Intuitively this also means &lt;a href="http://perlalchemy.blogspot.com/2011/01/dependency-injection-or-removing.html?showComment=1294250825469#c5152282940739512206"&gt;increasing the encapsulation of the main module&lt;/a&gt;.&lt;br /&gt;&lt;li&gt;To remove more frequently changing code from inside of less frequently changing code.  There is an analogy between hardcoded literal constants and hardcoded objects - this is the main subject of &lt;a href="http://perlalchemy.blogspot.com/2011/01/dependency-injection-or-removing.html"&gt;my previous post&lt;/a&gt;.&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;It is worth noting that Moose by taking over the &lt;code&gt;new&lt;/code&gt; method encourages DI, but of course people will always find ways to sidestep this by creating an &lt;code&gt;init&lt;/code&gt; or &lt;code&gt;setup&lt;/code&gt; method or using &lt;code&gt;BUILD&lt;/code&gt; or &lt;code&gt;BUILDARGS&lt;/code&gt; from the Moose API.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-1060930995947672853?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/1060930995947672853/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=1060930995947672853' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1060930995947672853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1060930995947672853'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/01/dependency-injection-some-updates.html' title='Dependency Injection - some updates'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-2055882965573865070</id><published>2011-01-04T23:45:00.000-08:00</published><updated>2011-01-06T13:20:43.926-08:00</updated><title type='text'>Dependency Injection or Removing Hardcoded Values?</title><content type='html'>Ever since I've heard about Dependency Injection (DI) a few years ago, I read and reread all the available documents and I kept having this feeling that I still miss something.  Yesterday after some googling - I found that even &lt;a href="http://plasmasturm.org/log/338/"&gt;those&lt;/a&gt; whom I always expected to explain things, have similar &lt;a href="http://plasmasturm.org/log/340/"&gt;problems with it&lt;/a&gt; (see also &lt;a href="http://use.perl.org/~Adrian/journal/27210"&gt;this interesting reply&lt;/a&gt; to that rant).  I am not sure if I now really understand DI, maybe I am still missing something important, but here is my tentative theory about it.&lt;br /&gt;&lt;br /&gt;Let us say that somewhere deep in your web app code you have these lines:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/766588.js?file=gistfile1.pl"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Every minimally experienced programmer will notice immediately that for any re-usability the database name, user and his password should be extracted into a place where they can be changed easily, like the first lines of the program or better a config file.  This would come very natural - but the reasoning behind it does not come from any theory - it is our experience that tells us that these pieces of data will change more frequently then the surrounding code.&lt;br /&gt;&lt;br /&gt;I don't know if anyone would call this Dependency Injection, I think he would rather say that he is removing &lt;b&gt;hardcoded&lt;/b&gt; constants.&lt;br /&gt;&lt;br /&gt;Now let's take this snippet:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/766589.js?file=gistfile1.pl"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;This is better - but the name of the &lt;code&gt;DBI&lt;/code&gt; class and the way you construct the &lt;code&gt;$dbh&lt;/code&gt; object is still &lt;b&gt;hardcoded&lt;/b&gt; here - the point about DI is that this is still wrong because these parts also will change more often then the rest of the &lt;code&gt;MyClass&lt;/code&gt;.  The most important case for this is tests.  In Perl it is possible to change the definition of the whole DBI package (mock it up) for the tests - but a more elegant solution is to move the database connection creation out of the &lt;code&gt;MyClass&lt;/code&gt; code:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/766591.js?file=gistfile1.pl"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;then, to test the &lt;code&gt;MyClass&lt;/code&gt; methods that don't use the &lt;code&gt;dbh&lt;/code&gt; field, you could pass an &lt;code&gt;undef&lt;/code&gt; there and not bother with setting the database at all.  But it is not only tests that require changes to that code - if for example at some point you decide that you want to log all the DBI warnings and add &lt;code&gt;{ PrintWarn =&gt; 1 }&lt;/code&gt; to the &lt;code&gt;DBI-&gt;connect&lt;/code&gt; call - this would also be easier with this design.  Again, just like with the initial example, I haven't seen any theory explaining this, but from my programming practice I am assured that this kind of change happens much more often, and at different phases of development, then changes to the rest of the &lt;code&gt;MyClass&lt;/code&gt; code.  Maybe the distinction is about &lt;b&gt;what&lt;/b&gt; i.e. values (literals or objects) and &lt;b&gt;how&lt;/b&gt; i.e. methods and subroutines - &lt;b&gt;what&lt;/b&gt; is more expected and easier to change - and to get the advantage of that ease you cannot mix it together with &lt;b&gt;how&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;The code removed in the last sample is a bit more complicated then in the initial example - but at the core it has the same nature - it is about computing some values that are later used across a program part (or the whole program).  In the initial example these values are literals, here they are objects.  Literals can be created independently, objects depend on other objects: we can have a &lt;code&gt;MyUser&lt;/code&gt; that depends on &lt;code&gt;MyClass&lt;/code&gt; that (as in our example) depends on the database connection.  Fortunately solving the dependency graph and finding out what needs to be created to have a &lt;code&gt;MyUser&lt;/code&gt; object can be automated - this is what the various DI frameworks (like &lt;a href="http://search.cpan.org/perldoc?Bread::Board"&gt;Bread::Board&lt;/a&gt;) do.  In more 'strictly' typed languages like Java - this dependency graph is mostly defined by the types used, in Perl the dependency needs to be defined by the programmer explicitly - but the graph solving works in the same way.  This is why this object creation code is (or can be made) quite simple and for all objects in the same scope it can fit into one package where you could adjust the various cooperating objects just like you do with the values of the configuration variables.&lt;br /&gt;&lt;br /&gt;This is my understanding of Dependency Injection - maybe I am still missing something - but I don't see where, in any non-convoluted way, there is the &lt;em&gt;Injection&lt;/em&gt; happening.  There are no new dependencies injected into the code.  Maybe more appropriate would Dependency Passing - as the dependencies are passed as parameters - but most of the work done when performing this refactorisation is &lt;b&gt;removing&lt;/b&gt; parts of code, parameter passing is the trivial part.  Additionally &lt;em&gt;Inversion of Control&lt;/em&gt;, which is used to explain DI in many places, is just a minor characteristic of it, not very visible one and very different from other more common &lt;em&gt;Inversion of Control&lt;/em&gt; occurrences.  Mark Fawler &lt;a href="http://martinfowler.com/articles/injection.html"&gt;coined the term Dependency Injection&lt;/a&gt; specifically to differ it from &lt;em&gt;Inversion of Control&lt;/em&gt;  in general - but I think that even presenting it as an example of IoC is misleading, because it is not very important to understand what is going on and it is so different from the &lt;a href="http://en.wikipedia.org/wiki/Hollywood_Principle"&gt;Hollywood Principle&lt;/a&gt; that everyone thinks about when reading &lt;em&gt;Inversion of Control&lt;/em&gt;.  Finally what is frequently blurring explanations of DI is the details of the DI frameworks used and dwelling over &lt;em&gt;constructor injections&lt;/em&gt; or &lt;em&gt;setter injections&lt;/em&gt; - i.e. going into the &lt;b&gt;how&lt;/b&gt; before the &lt;b&gt;why&lt;/b&gt; is well explained.  &lt;br /&gt;&lt;br /&gt;I believe that &lt;em&gt;removing hardcoded values&lt;/em&gt; is what Dependency Injection is really about.  Most programmers already have good intuitions on why this is needed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-2055882965573865070?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/2055882965573865070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=2055882965573865070' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2055882965573865070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2055882965573865070'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2011/01/dependency-injection-or-removing.html' title='Dependency Injection or Removing Hardcoded Values?'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3553589167196516246</id><published>2010-12-23T00:53:00.000-08:00</published><updated>2010-12-23T02:20:14.831-08:00</updated><title type='text'>Images inheritance in Plack based apps</title><content type='html'>My plan for Nblog is to let users customize it by subclassing and overloading, in the screencast I showed how to do that with controllers and templates, in the latest revision of Nblog I added the possibility of overloading images.  There are Plack components for all parts of this task - but I had a bit of struggle with getting the settings right.  Maybe the following code snippet will spare similar time waste for someone?&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/752761.js?file=NblogConstructor.pm"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Some explanations: &lt;code&gt;psgi_callback&lt;/code&gt; is the method in WebNano that constructs the anonymous subroutine required by the &lt;a href="http://search.cpan.org/perldoc?PSGI"&gt;PSGI&lt;/a&gt; standard and here I use the &lt;a href="http://search.cpan.org/perldoc?Moose::Manual::MethodModifiers"&gt;around Moose method modifier&lt;/a&gt; for it to add some additional processing there. &lt;code&gt;static_roots&lt;/code&gt; returns a list of directories where to search for the static files - this is our search path - the first file found in these directories is served.  In the base class this list contains only &lt;code&gt;'static'&lt;/code&gt; - if you want to overload the static files in a subclass you need to add your directories before this one, in my example subclass config I have:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;static_root =&gt; [ 'static', '../Nblog/static' ]&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;(these are relative paths).  See also &lt;a href="http://search.cpan.org/perldoc?Plack::App::Cascade"&gt;Plack::App::Cascade&lt;/a&gt;.  All of this would be a bit easier to assemble if the Plack components logged some debug info to STDOUT, like what you can find in the standard Apache logs about files not found, when run in development environment.  I am volunteering to write a patch if there is a green light from the core devs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3553589167196516246?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3553589167196516246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3553589167196516246' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3553589167196516246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3553589167196516246'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/12/images-inheritance-in-plack-based-apps.html' title='Images inheritance in Plack based apps'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-4690039424447328102</id><published>2010-12-20T04:47:00.000-08:00</published><updated>2010-12-20T05:37:38.717-08:00</updated><title type='text'>Unit Testing</title><content type='html'>With one functional/system test you can test lot's of low level parts that in &lt;a href="http://en.wikipedia.org/wiki/Unit_testing"&gt;Unit Testing&lt;/a&gt; would require a separate test each.  It is also easier to write - because you only need to test how the module/library is used and using it should be easy (and not require mocking etc) - otherwise the library would not be a good library to start with.  And what are the reasons to do unit testing?  Personally I was never convinced by the arguments until I started reading Misko Hevery - here is for example is the single best explanation of why to do unit testing I've ever seen:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Lets say you would like to test a car, which you are in the process of designing, would you test is by driving it around and making modifications to it, or would you prove your design by testing each component separately? I think that testing all of the corner cases by driving the car around is very difficult, yes if the car drives you know that a lot of things must work (engine, transmission, electronics, etc), but if it does not work you have no idea where to look. However, there are some things which you will have very hard time reproducing in this end-to-end test. For example, it will be very hard for you to see if the car will be able to start in the extreme cold of the north pole, or if the engine will not overheat going full throttle up a sand dune in Sahara. I propose we take the engine out and simulate the load on it in a laboratory.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;from &lt;a href="http://misko.hevery.com/2009/09/02/it-is-not-about-writing-tests-its-about-writing-stories/"&gt;It is not about writing tests, its about writing stories&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In the rest of his writings you'll also find how to structure your code in a way that makes unit testing easy and does not require crazy mockings.  I am also convinced that code structured in that way is well decoupled and easy to understand, modify and talk about.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-4690039424447328102?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/4690039424447328102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=4690039424447328102' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4690039424447328102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4690039424447328102'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/12/unit-testing.html' title='Unit Testing'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3165514404704657503</id><published>2010-12-17T14:16:00.001-08:00</published><updated>2010-12-17T14:29:37.947-08:00</updated><title type='text'>Experiments in Inheritance - a screencast</title><content type='html'>This is a short screencast I made to replace the video made at my London Perl Workshop presentation.  It did not make the &lt;a href="http://www.presentingperl.org/lpw2010/"&gt;list&lt;/a&gt; eventually - but I still think it might be interesting: &lt;a href="http://warszawa.pm.org/WebNanoInheritance.mpeg"&gt;http://warszawa.pm.org/WebNanoInheritance.mpeg&lt;/a&gt;.  It is my first screencast ever made - please comment.&lt;br /&gt;&lt;br /&gt;The main idea presented there is about solving the "give mi an application like this one but ..." problem, illustrated by making a blog engine that inherits from &lt;a href="https://github.com/zby/Nblog"&gt;Nblog&lt;/a&gt;, but extends it and overrides some of it's elements.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3165514404704657503?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3165514404704657503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3165514404704657503' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3165514404704657503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3165514404704657503'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/12/experiments-in-inheritance-screencast.html' title='Experiments in Inheritance - a screencast'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3050405353890326216</id><published>2010-12-13T23:17:00.000-08:00</published><updated>2010-12-13T23:34:15.871-08:00</updated><title type='text'>Namespace Matching</title><content type='html'>The other day I was reading the Dancer Advent Calendar and I finally found the two words description of what WebNano does.  WebNano is the minimal addition to PSGI that provides Namespace Matching.  Beside easy deployment, which is currently covered by Plack, Namespace Matching is probably the main feature of Catalyst and now with WebNano you can have that without the heavy baggage of the whole of the Catalyst framework.  I think it is important because it seems to produce just the right granularity of the controller classes and provides a path for the application growth (without overloading one file with too much stuff).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3050405353890326216?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3050405353890326216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3050405353890326216' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3050405353890326216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3050405353890326216'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/12/namespace-matching.html' title='Namespace Matching'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-4697966874838303377</id><published>2010-12-05T02:51:00.001-08:00</published><updated>2010-12-05T05:32:52.078-08:00</updated><title type='text'>WebNano - some incompatible API changes ahead</title><content type='html'>I tried carefully not to document some things that are likely to change in the closest WebNano releases, but the example code I put in the docs needs to be exact and that means it contains some details I have not yet decided are stable.  One of these examples is about overriding the &lt;code&gt;local_dispatch&lt;/code&gt;.  It used to take the path as a string parameter - now it takes an array - i.e. the path split on the '/' character.  The past way was more universal as it let the user programmer to specify how to parse the path - but I think splitting on '/' is such a common usage that it justifies the change. And it is not destructive - so if someone really want's to parse the path in a different way then he can join it back.&lt;br /&gt;&lt;br /&gt;This change will be in the next WebNano release.&lt;br /&gt;&lt;br /&gt;In the longer perspective I am thinking about being more compliant with the &lt;a href="http://en.wikipedia.org/wiki/Law_of_Demeter"&gt;Law of Demeter&lt;/a&gt; and building the controllers with the needed model parts in their own attributes, instead of accessing them through &lt;code&gt;app&lt;/code&gt;.  So for example some code in Nblog would change from &lt;br /&gt;&lt;br /&gt;&lt;code&gt;$self-&gt;app-&gt;schema-&gt;resultset( 'Article' )-&gt;search&lt;/code&gt; &lt;br /&gt;to&lt;br /&gt;&lt;code&gt;$self-&gt;article_rs-&gt;search&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now this can be done by overriding the &lt;code&gt;handle&lt;/code&gt; class method - but maybe it needs something more elegant.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-4697966874838303377?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/4697966874838303377/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=4697966874838303377' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4697966874838303377'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4697966874838303377'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/12/webnano-some-incompatible-api-changes.html' title='WebNano - some incompatible API changes ahead'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-4161579699806670957</id><published>2010-12-01T04:52:00.000-08:00</published><updated>2010-12-02T05:03:54.509-08:00</updated><title type='text'>WebNano as Catalyst::Tiny</title><content type='html'>If you have read &lt;a href="http://www.perl.com/pub/2010/11/the-philosophy-of-webnano.html"&gt;The Philosophy of WebNano&lt;/a&gt; you might think that WebNano is radically different from Catalyst, the more so if you'd compare the size of these projects (sloccount reports over 5000 lines in lib for Catalyst, versus less then 250 for WebNano).  But if you compare the code structure between &lt;a href="https://github.com/zby/Nblog"&gt;Nblog&lt;/a&gt; and the original &lt;a href="https://github.com/gshank/ravlog"&gt;RavLog&lt;/a&gt; project you'll find it very similar.  The DBIC schema and form classes were just copied around, you'll see mostly the same controllers with mostly the same methods.  &lt;br /&gt;&lt;br /&gt;Look for example at &lt;a href="https://github.com/zby/Nblog/blob/master/lib/Nblog/Controller/Ajax.pm"&gt;Nblog::Controller::Ajax&lt;/a&gt; and &lt;a href="https://github.com/gshank/ravlog/blob/master/lib/RavLog/Controller/Ajax.pm"&gt;RavLog::Controller::Ajax&lt;/a&gt; - the changes are minimal, mostly just changing &lt;code&gt;sub check_articles : Local&lt;/code&gt; to &lt;code&gt;sub check_articles_action&lt;/code&gt; and accessing the model from &lt;code&gt;$c-&gt;model('DB::Tag')-&gt;search&lt;/code&gt; to &lt;code&gt;$self-&gt;app-&gt;schema-&gt;resultset( 'Tag')-&gt;search&lt;/code&gt; - a bit longer perhaps.  Sure there are other controllers like: &lt;a href="https://github.com/gshank/ravlog/blob/master/lib/RavLog/Controller/View.pm"&gt;RavLog::Controller::View&lt;/a&gt; that I renamed to &lt;a href="https://github.com/zby/Nblog/blob/master/lib/Nblog/Controller/Article.pm"&gt;Nblog::Controller::Article&lt;/a&gt;.  This renaming is not important - I just did not like a controller called View but there is also some difference in their methods. The RavLog controller uses the Chained Catalyst dispatcher - while in the Nblog one I overrode &lt;code&gt;local_dispatch&lt;/code&gt;, and it uses stash to communicate with the template while in Nblog I passe the data directly as a parameter.  Still some similarity remains.&lt;br /&gt;&lt;br /&gt;WebNano uses some dependencies - so it does not fit into the original Adam's definition of tiny modules (by the way I cannot fin this definition now - maybe this should go to some semi-official place like the p5p wiki?).  But the prerequisites are really minimal - and mostly tiny themselves. Maybe in the subject space of web frameworks this should be allowed?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-4161579699806670957?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/4161579699806670957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=4161579699806670957' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4161579699806670957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4161579699806670957'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/12/webnano-as-catalysttiny.html' title='WebNano as Catalyst::Tiny'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3785771419711511041</id><published>2010-11-25T01:16:00.000-08:00</published><updated>2010-11-25T01:17:42.794-08:00</updated><title type='text'>Why WebNano - the article</title><content type='html'>My &lt;a href="http://www.perl.com/pub/2010/11/the-philosophy-of-webnano.html"&gt;article on the motivation for WebNano&lt;/a&gt; was published at perl.com.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3785771419711511041?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3785771419711511041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3785771419711511041' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3785771419711511041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3785771419711511041'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/11/why-webnano-article.html' title='Why WebNano - the article'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6264457385593784313</id><published>2010-11-15T09:04:00.000-08:00</published><updated>2010-11-15T10:46:30.698-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Old code and survivor bias</title><content type='html'>If code is well designed, decoupled and has good test coverage there are chances that it will be regularly updated to new technologies and new programming techniques.  The other code will probably scare programmers and have much chance to stay in it's sad state until decommission.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6264457385593784313?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6264457385593784313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6264457385593784313' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6264457385593784313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6264457385593784313'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/11/old-systems-and-survivor-bias.html' title='Old code and survivor bias'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6118886713457039900</id><published>2010-11-06T12:17:00.000-07:00</published><updated>2010-11-06T12:43:16.329-07:00</updated><title type='text'>Templates</title><content type='html'>I've heard that Perl is ugly because of all those pesky '$'.  Purely esthetically this might be true, depending on the font used, but I have the impression that people use the word 'ugly' in a more metaphorical way, like 'ugly subroutine'.  Somehow they believe that using an otherwise unused character for marking variables is inelegant - but I think they are confused, I think their opposition arises from the kneejerk reaction to an unfamiliar character.  For me the '$' signs make parsing and understanding Perl code easier.&lt;br /&gt;&lt;br /&gt;I've heard that TT2 code is ugly because it uses '[%' instead of the more familiar '&lt;', and that it 'FOR' is a heavy burden for the eyes of the programmer because it is "shouting" at him, but I think that the features that make TT2 code standout in the text being templated make it easier to parse and understand and they help my eyes in their work.&lt;br /&gt;&lt;br /&gt;Beside that purely ergonomical argument I don't see any purpose of the mini language and I think I am not that thrilled by the &lt;a href="http://tt3.template-toolkit.org/docs/Template/TT3/Manual/Tags.html"&gt;future direction of TT&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6118886713457039900?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6118886713457039900/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6118886713457039900' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6118886713457039900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6118886713457039900'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/11/templates.html' title='Templates'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-2426672273647673286</id><published>2010-10-20T11:54:00.000-07:00</published><updated>2010-10-20T14:15:51.594-07:00</updated><title type='text'>WebNano</title><content type='html'>In the weekend I published &lt;a href="http://search.cpan.org/search?query=WebNano&amp;mode=all"&gt;WebNano to CPAN&lt;/a&gt;.  There is some documentation there - so it is ready for experimenting.  I am thinking about a "Why WebNano" article.  For now let me just say this: WebNano has just 232 lines of code in 'lib' (as reported by sloccount) and beside Plack it uses only &lt;a href="http://deps.cpantesters.org/?module=WebNano;perl=latest"&gt;minimal dependencies&lt;/a&gt;, but when porting a non-trivial &lt;a href="http://github.com/zby/Nblog"&gt;blog engine&lt;/a&gt; from Catalyst to WebNano I did not miss any Catalyst features.  To be honest in that conversion I did use two WebNano extensions (both also already published), Template Toolkit renderer with dynamic paths and a CRUD controller, but even including them the line count would not excede 500.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-2426672273647673286?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/2426672273647673286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=2426672273647673286' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2426672273647673286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2426672273647673286'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/10/webnano.html' title='WebNano'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-29786785800448161</id><published>2010-10-18T13:06:00.000-07:00</published><updated>2010-10-19T04:17:44.396-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Extending the 'Template Method' design pattern</title><content type='html'>There is this notion that you should not put semantics into names, or maybe that what your program do should not change in &lt;a href="http://en.wikipedia.org/wiki/Lambda_calculus#.CE.B1-conversion"&gt;alpha-conversion&lt;/a&gt;.  But of course everyone is breaking that rule if she is using the &lt;a href="http://en.wikipedia.org/wiki/Template_method_pattern"&gt;Template Method&lt;/a&gt; design pattern (if we agree that the library they use is somehow outside of the program and is not alpha-converted together with it).  There the names of methods have a lot of semantics.  &lt;br /&gt;&lt;br /&gt;In &lt;a href="http://www.catalystframework.org/calendar/2007/16"&gt;Advanced Search in web DBIx::Class based applications&lt;/a&gt; I proposed an extension to DBIx::Class that would treat all methods with names &lt;code&gt;search_for_*&lt;/code&gt; as predicate builders.  This way programmers could easily extend the &lt;a href="http://search.cpan.org/dist/SQL-Abstract/"&gt;query language&lt;/a&gt; used by DBIx::Class with new predicates by adding methods to the ResultSet class.  Now in &lt;a href="http://search.cpan.org/search?query=WebNano&amp;mode=all"&gt;WebNano&lt;/a&gt; all &lt;code&gt;*_action&lt;/code&gt; controller methods also have a special meaning - these are the methods that can be called from outside via automatic dispatching from an url.  Taken literally &lt;code&gt;sub my_method_action &lt;/code&gt; is not that different from &lt;code&gt;sub my_method : Action &lt;/code&gt; which is the way to specify that in Catalyst. The difference is only ' : A' versus '_a' (and I could use *_Action if I wanted to golf it even more) - but yeah - I am cramming the semantics into the name while Catalyst reserves it for the code attributes.  Catalyst way is cleaner - but my goal was a 'minimal' framework.  The 'Extended Template Method' design works in a few lines while &lt;a href="http://search.cpan.org/dist/MooseX-MethodAttributes/"&gt;MooseX-MethodAttributes&lt;/a&gt; is 13 packages with who knows how many lines of very subtle code.&lt;br /&gt;&lt;br /&gt;What surprises me is that I have never seen a description of this 'Extended Template Method' design pattern.  It looks rather obvious, maybe it is called by some other name in the literature.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-29786785800448161?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/29786785800448161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=29786785800448161' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/29786785800448161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/29786785800448161'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/10/extending-template-method-design.html' title='Extending the &apos;Template Method&apos; design pattern'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-8804030082460660630</id><published>2010-10-12T13:14:00.000-07:00</published><updated>2010-10-12T13:28:27.217-07:00</updated><title type='text'>Inviting non-Perlers to speak at Perl conferences</title><content type='html'>There is &lt;a href="https://www.socialtext.net/perl5/index.cgi?events"&gt;an organized effort, by the Perl volunteer marketers, to attend non-Perl events&lt;/a&gt; and communicate about the all new things happening in the otherwise insulated Perl word.  I wish this effort all the best, and I hope that The Perl Foundation will find a way to support it.  To enforce the effect I would like to see also the symmetric and complementary action of inviting non-Perlers to our conferences.  I am sure that is already happening to some extent - but personally I have not yet seen it - so I conclude that this extent is not enough.&lt;br /&gt;&lt;br /&gt;Whom, from non-Perl speakers, would you like to hear at your next Perl conference?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-8804030082460660630?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/8804030082460660630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=8804030082460660630' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8804030082460660630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8804030082460660630'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/10/inviting-non-perlers-to-speak-at-perl.html' title='Inviting non-Perlers to speak at Perl conferences'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-4054679600205373496</id><published>2010-09-30T00:11:00.000-07:00</published><updated>2010-09-30T02:44:17.425-07:00</updated><title type='text'>Value Objects - some notes</title><content type='html'>There is a controversy - or maybe a fuzzy consensus about what you &lt;a href="http://www.mail-archive.com/catalyst@lists.scsys.co.uk/msg05729.html"&gt;should be able to do in templates&lt;/a&gt;.  Some template engines, like Template Tookit, let you call subroutines and methods on stuff passed to the template.  This is very useful - you don't need to care about turning the data into a specially formed hash that can be iterated by the template, you just pass the data there and can be sure that it can display it.  But it can also be abused.  I think everyone would agree that template should not for example change the data in the database, but where is exactly the limit is not clear.  &lt;a href="https://docs.google.com/present/view?id=d449gch_225g37rfqhp"&gt;Value Objects&lt;/a&gt; seem to be a good answer, templates should work only with Value Objects.&lt;br /&gt;&lt;br /&gt;The question is how sharply you can divide your objects into Value Objects and Service Objects.  In &lt;a href="http://misko.hevery.com/2009/06/29/active-record-hard-to-test/"&gt;ActiveRecord is hard to test&lt;/a&gt; Hevery proposes a design where the record in Active Record is a Value Object (newable in his terminology is a synonym) with no link to the repository object which would do all the database manipulation.  This would work for normal attributes - you'd assign the value there on object creation - but what about relations?  &lt;code&gt;$user-&gt;books&lt;/code&gt; is very convenient, especially in templates, and it can be pure - if you know that you need the books on the user you could put them there when creating the user object. But then you'd have two kinds of objects - those with books, needed in some places - and those without, when you want to spare the additional database calls. Maybe we need subclasses of &lt;code&gt;User&lt;/code&gt;?  But then we'd need subclasses for all possible combinations of relations (users with books, users with friends, users with books and friends, ...), not to mention the mess with relations on the related objects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-4054679600205373496?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/4054679600205373496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=4054679600205373496' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4054679600205373496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4054679600205373496'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/09/value-objects-some-notes-on-stuff-by.html' title='Value Objects - some notes'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6577415332098176261</id><published>2010-09-26T22:35:00.000-07:00</published><updated>2010-09-27T00:01:04.631-07:00</updated><title type='text'>Another argument for immutable objects</title><content type='html'>Class is like a little program, it has data, it has code, it can be instantiated -  like a program can be run.  From the perspective of the object it's attributes are global.  There can also be other variables - like parameters passed to the methods or other block scoped variables - those are local, but attributes are global.  If they are immutable - they are like programs constants, but when they are changeable - they are like global variables.  And we know that global variables are bad.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6577415332098176261?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6577415332098176261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6577415332098176261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6577415332098176261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6577415332098176261'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/09/another-argument-for-immutable-objects.html' title='Another argument for immutable objects'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-1555489546586389405</id><published>2010-09-25T06:29:00.000-07:00</published><updated>2010-09-27T00:02:39.327-07:00</updated><title type='text'>Managing Object Lifetime</title><content type='html'>This is the title of a &lt;a href="http://misko.hevery.com/2009/04/15/managing-object-lifetimes/"&gt;blog post by Misko Hevery&lt;/a&gt;.  There are also lot's of other &lt;a href="http://www.youtube.com/watch?v=acjvKJiOvXw&amp;feature=channel"&gt;materials&lt;/a&gt; &lt;a href="http://misko.hevery.com/2008/07/30/top-10-things-which-make-your-code-hard-to-test/"&gt;authored by him&lt;/a&gt; freely available on the net.  I have just started exploring them, and there is a lot of repetition if you just google around like me - but I already want to recommend it to anyone working on improving the design of their programs.  &lt;br /&gt;&lt;br /&gt;WebNano does not (yet?) meet all the design criteria he is talking about - but he is putting into words many of the foggy &lt;a href="http://perlalchemy.blogspot.com/2009/12/scope-and-immutability.html"&gt;intuitions&lt;/a&gt; that made me not satisfied with all of the existing Perl web framework and write yet another one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-1555489546586389405?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/1555489546586389405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=1555489546586389405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1555489546586389405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1555489546586389405'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/09/managing-object-lifetime.html' title='Managing Object Lifetime'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-2456190341959531894</id><published>2010-09-23T06:12:00.000-07:00</published><updated>2010-09-23T06:46:06.360-07:00</updated><title type='text'>Inheritance and rapid prototyping</title><content type='html'>There is much talk about the dangers of too much inheritance and how composition is better then inheritance - and probably they are right if we are talking about the final product.  What they don't account for are the dynamics of the development - where you grab the first thing that does something similar to what you need and you start testing it, changing it, evaluating your ideas.  Inheritance allows you to do exactly that - making changes to something that was already finished and working somewhere else.   With procedural code this is not possible, the most similar thing you can get there are examples.&lt;br /&gt;&lt;br /&gt;In other words Inheritance might lead to tightly coupled code, with intricate execution paths, but at least it is an easy way to get something working quickly.  You can refactor it later.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-2456190341959531894?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/2456190341959531894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=2456190341959531894' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2456190341959531894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2456190341959531894'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/09/inheritance-and-rapid-prototyping.html' title='Inheritance and rapid prototyping'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3452909800874907402</id><published>2010-09-16T12:29:00.000-07:00</published><updated>2010-09-19T13:31:04.244-07:00</updated><title type='text'>Installing Dist::Zilla plugins</title><content type='html'>Dear lazyweb - when I try out a distribution converted to DistZilla I often discover that I don't have all the plugins used there.  Starting the work then consists of a string of 'dzil build' commands, searching the monstrous error stacks for the name of the missing plugin and then running cpan with it.  Sure that should be automated!&lt;br /&gt;&lt;br /&gt;And, by the way, it could also install the distribution's prerequisites.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt; Repeating one of the comments - apparently the latest Dist::Zilla supports following solution &lt;code&gt;dzil authordeps | cpanm&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3452909800874907402?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3452909800874907402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3452909800874907402' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3452909800874907402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3452909800874907402'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/09/installing-distzilla-plugins.html' title='Installing Dist::Zilla plugins'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-35484633785133016</id><published>2010-08-14T02:36:00.000-07:00</published><updated>2010-08-14T04:14:33.665-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Object::Tiny:RW and MooseX::NonMoose</title><content type='html'>There are conflicting requirements for WebNano.  On one hand I would like to build big  heavy web applications based on it, and of course I would like to use Moose as the object framework for them.  On the other hand I would like to give it a chance to work in the restricted environments of most shared web hosting serving CGI scripts - so heavy dependencies and XS and big startup times are out.  And I would also like to make it suitable for serving huge amounts of simple Ajax requests - so it needs to be fast.&lt;br /&gt;&lt;br /&gt;First I tried using Any::Moose and let people decide if they used Moose or Mouse.  By using Mouse people could solve the startup problem and also there is some way to use Mouse without XS. &lt;br /&gt;&lt;br /&gt;But Mouse was still huge dependency - so next I asked myself it it would be possible to subclass in Moose a non Moose base classes.  That proved to be rather simple with the aptly named &lt;a href="http://search.cpan.org/~doy/MooseX-NonMoose/"&gt;MooseX::NonMoose&lt;/a&gt;. Using it in WebNano I can build my objects in what ever way I choose and as long as I stick to the standard hash based objects I can extend the WebNano classes in my Moose based applications with no problems.  Or at least it seems to be with no problems for me now - if someone knows more about disadvantages of this solution - please leave a comment.&lt;br /&gt;&lt;br /&gt;After discovering MooseX::NonMoose I switched to use &lt;a href="http://search.cpan.org/~smueller/Class-XSAccessor/"&gt;Class::XSAccessor&lt;/a&gt;.  It small and very fast, but unfortunately it was XS based.  I was thinking about the possibilities of bundling the software as a PAR package or so and using it in the restricted shared hosting environments and relying on a C compiler seemed to complicate things a lot.  &lt;br /&gt;&lt;br /&gt;Next I tried &lt;a href="http://search.cpan.org/~adamk/Object-Tiny/"&gt;Object::Tiny&lt;/a&gt;, it was tiny, fast and did not use XS, there was just one but - it did not produce the attribute setters.  I could live with that and it did not take much time for me to port WebNano to use Object::Tiny, but still it seemed like an extreme choice.  Fortunately just browsing CPAN I discovered a fork of O::T - &lt;a href="http://search.cpan.org/~schwigon/Object-Tiny-RW/"&gt;Object::Tiny::RW&lt;/a&gt; - this one is small, fast, does not use XS and does produce attribute setters.  I am still a bit worry about why Adam would not add that feature to his module - given that it is such a trivial change (compare the sources of &lt;a href="http://cpansearch.perl.org/src/SCHWIGON/Object-Tiny-RW-1.06/lib/Object/Tiny/RW.pm"&gt;Object::Tiny::RW&lt;/a&gt; and &lt;a href="http://cpansearch.perl.org/src/ADAMK/Object-Tiny-1.06/lib/Object/Tiny.pm"&gt;Object::Tiny&lt;/a&gt; - its just one line changed), he must have had a good reason for that?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-35484633785133016?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/35484633785133016/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=35484633785133016' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/35484633785133016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/35484633785133016'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/08/objecttinyrw-and-moosexnonmoose.html' title='Object::Tiny:RW and MooseX::NonMoose'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-7344822717975912315</id><published>2010-08-07T05:56:00.000-07:00</published><updated>2010-08-07T06:12:45.452-07:00</updated><title type='text'>RavLog - a perl blog engine</title><content type='html'>For testing HTML::FormHandler Gerda Shank wrote &lt;a href="http://github.com/gshank/ravlog"&gt;RavLog&lt;/a&gt;.  Recently I've made a &lt;a href="http://github.com/zby/ravlog"&gt;fork of it&lt;/a&gt;, switched to SQLite as the main db engine and made it easy to install.  It still does not pass all formatting tests (&lt;a href="http://search.cpan.org/~petdance/HTML-Tidy-1.52/"&gt;HTML::Tidy&lt;/a&gt; seems to be uninstallable) - but it is usable.  My goal is to make another fork out of it and port at least part of it to WebNano, but I think that what is now there can also be interesting for someone looking for a Catalyst based weblog engine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-7344822717975912315?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/7344822717975912315/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=7344822717975912315' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/7344822717975912315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/7344822717975912315'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/08/ravlog-perl-blog-engine.html' title='RavLog - a perl blog engine'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-8112196753232343403</id><published>2010-07-09T03:48:00.001-07:00</published><updated>2010-07-09T12:41:33.354-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Technically right, socially not so</title><content type='html'>Imagine that you let anyone use your hard work by publishing your code as Open Source and then instead of thank you notes you receive angry emails about purported bugs in it.&lt;br /&gt;&lt;br /&gt;Imagine that you noticed a problem about some Open Source code and as a good citizen you analyze it and report your findings and instead of a thank you note you receive a reply explaining how much confused you are for thinking that that could be a bug.&lt;br /&gt;&lt;br /&gt;Imagine that this happens in a public space like an mailing list, open bug tracker, etc.  This is like the setting of a Greek tragedy - both sides have their own rights and values, both sides can be technically right - and yet the conflict spreads and escalates.  People copy the emotions of each other, even perceived emotions and especially anger, when displayed publicly leads to more anger.  This is a vicious circle of positive feedback loop.  When it starts everyone gets irritated and everyone wants to know who started it, who is responsible for that.&lt;br /&gt;&lt;br /&gt;But go back to the start - it's not anyone's fault - you cannot point the finger on one person and say 'he is responsible'.  Looking for the main culprit is really looking for a scapegoat - a surrogate victim that would heal everyone's consciousness. This is not especially geek thing overall - it is a universal trait - but sadly inventing fodder for the scapegoat search is &lt;a href="http://catb.org/esr/faqs/smart-questions.html"&gt;a prominent part of geek culture&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;One of the many things that I admire about Larry Wall is how he can neutralize the poisons of angry reactions.  People scorn Perl for being a 'scripting' language - &lt;a  href="http://www.perl.com/pub/a/2007/12/06/soto-11.html"&gt;he talks about Ada Lovelace&lt;/a&gt;: &lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Suppose you went back to Ada Lovelace and asked her the difference between a script and a program. She'd probably look at you funny, then say something like: Well, a script is what you give the actors, but a program is what you give the audience. That Ada was one sharp lady...&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-8112196753232343403?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/8112196753232343403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=8112196753232343403' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8112196753232343403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8112196753232343403'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/07/technically-right-socially-not-so.html' title='Technically right, socially not so'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-4790725300650587443</id><published>2010-07-07T23:58:00.000-07:00</published><updated>2010-07-08T00:33:14.921-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Installing dependencies - continued</title><content type='html'>I don't know what I am doing wrong - but after installing Perl 5.12.1 under perlbrew "cpan -m ." stopped to install the dependencies.  It seems that for making and testing it adds the libs in '.cpan/build' to the PERL5LIB search path so both can go on without really installing the dependencies:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Running make for /home/zby/progs/ravlog/.&lt;br /&gt;Prepending blib/arch and blib/lib of 108 build dirs to PERL5LIB; for 'get'&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;"cpan -t . " works in the same way and if the tests fail then "cpan ." stops there - so I cannot tell if it would install the dependencies in the case when the tests pass.&lt;br /&gt;&lt;br /&gt;I don't really know how to investigate it further - but I am noting that as it is very frustrating.  Eventually I had to resort to cpanminus ("cpanm --installdeps ." is really handy as it addresses the problem directly).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-4790725300650587443?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/4790725300650587443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=4790725300650587443' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4790725300650587443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4790725300650587443'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/07/installing-dependencies-continued.html' title='Installing dependencies - continued'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-2696093876320345854</id><published>2010-06-24T04:20:00.000-07:00</published><updated>2010-06-24T06:27:19.259-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Implementing file upload progress bar</title><content type='html'>&lt;a href="http://philpapers.org/"&gt;At work&lt;/a&gt; I was assigned the task of replacing the previous hodgepodge of tools that provide the progress bar functionality for forms with file uploads.  At first glance this seems like a trivial thing to do - you periodically observe how much of the file you've got and update the progress bar, but there are details that make it hard to do with the current tools.  I report here how I solved that problem - not because I think this is the optimal way - but rather to open the discussion and because I could not find any description of solving it when I googled for it.&lt;br /&gt;&lt;br /&gt;First of all the common programming tools (like CGI.pm or Mason that we use here) assume that the page handler receives the whole request as input - and that whole request is not available until after the file is uploaded. So for example 'my $q = CGI.pm-&gt;new' will not finish until it is too late to measure the upload progress.  The solution to that is to use another page to report the upload progress and call that page via Ajax from Javascript code updating the progress bar.  This would work great - but the file is normally uploaded to a temporary file with a random name and the other script would not have any chance to guess it.  We need to generate a new random file name in the form page and then pass that name to the form handler script so that it would save the data to that file, and in parallel to the Ajax scripts that would check the size of that file.      &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To save the data into a specified filename I used the CGI.pm &lt;a href="http://search.cpan.org/~lds/CGI.pm-3.49/lib/CGI.pm#Progress_bars_for_file_uploads_and_avoiding_temp_files"&gt;callback feature&lt;/a&gt;:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;my $q = CGI-&gt;new( \&amp;hook, $fh, undef );&lt;br /&gt;...&lt;br /&gt;sub hook {&lt;br /&gt;    my ($filename, $buffer, $bytes_read, $fh) = @_;&lt;br /&gt;    print $fh substr($buffer, 0, $bytes_read);&lt;br /&gt;    $fh-&gt;flush();&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;It is described in the subsection called "Progress bars for file uploads and avoiding temp files" of the CGI.pm documentaion, but actually it is a great leap of thought to say that it supports progress bar implementation, you still cannot use it directly to get the progress bar from the CGI object on the form landing page, you still need the separate scripts measuring the progress.  For my solution all I needed was to pass the target file name to the code saving the data, this could be easier than writing this callback above. And the callback is still not everything - I yet need a way to pass the generated filename from the form page to that script - and not via form parameters, remember they are not available at that stage.  So how can that be done? Simple - as PATH_INFO - which is available in the %ENV hash even before the params are parsed by CGI.pm.&lt;br /&gt;&lt;br /&gt;This is the skeleton of the solution - there are a few more details in the actual implementation - but the code will be published soon as Open Source - so I hope everyone will be able to look them up there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-2696093876320345854?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/2696093876320345854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=2696093876320345854' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2696093876320345854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2696093876320345854'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/06/implementing-file-upload-progress-bar.html' title='Implementing file upload progress bar'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6808247933732701759</id><published>2010-06-19T09:21:00.000-07:00</published><updated>2010-06-19T11:10:38.939-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>When those micro-seconds matter</title><content type='html'>Catalyst is the only web framework that has a mailing list I subscribe to - but I am sure that it happens at others too.  In a recurring pattern someone &lt;a href="http://www.gossamer-threads.com/lists/engine?do=post_view_flat;post=12002;page=1;mh=-1;list=catalyst;sb=post_latest_reply;so=ASC"&gt;someone posts&lt;/a&gt; a &lt;a href="http://www.gossamer-threads.com/lists/engine?do=post_view_flat;post=26724;page=1;mh=-1;list=catalyst;sb=post_latest_reply;so=ASC"&gt; benchmark&lt;/a&gt; showing that Catalyst for some trivial operation is many times (or many hundred times) slower than some other web framework or for that matter PHP.  That does not fail to generate a heated debate - but eventually the seasoned framework developers gain the upper hand with the argument that for all the, often big, web sites they worked on, those few micro-seconds lost in the Catalyst dispatcher never mattered much because the application spent hundred times more in other code fragments and mostly in business logic parts, so shaving off some part of the few micro-seconds would not improve the overall speed more than 1%.  This is a great argument, perfectly reasonable and rational but it is biased towards the status quo. It might be true that  everywhere where Catalyst is currently used it works great but it is also not hard to imagine an application with very simple business logic that needs to serve millions of users, Twitter anyone?  Or an app that does many simple Ajax callbacks.  Sure you can always code the speed requiring, simple parts in PHP and keep Catalyst only for the other more heavy-weight tasks but having a universal solution would be so much more convenient.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6808247933732701759?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6808247933732701759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6808247933732701759' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6808247933732701759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6808247933732701759'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/06/when-those-micro-seconds-matter.html' title='When those micro-seconds matter'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3378928960117695179</id><published>2010-06-13T05:46:00.000-07:00</published><updated>2010-06-14T11:08:53.391-07:00</updated><title type='text'>Installing dependencies for your packaged for CPAN library</title><content type='html'>&lt;b&gt;Update:&lt;/b&gt; See the comments, apparently the warning against auto_install is outdated information.  I don't have any opinion of myself here.&lt;br /&gt;&lt;br /&gt;It always puzzled me what is the 'canonical' way to install dependencies for an unpacked distribution, be it downloaded from CPAN or your own in-house product packaged the CPAN way for convenience.  Module::Install provides an 'auto_install' option that you add to your Makefile.PL and then &lt;code&gt;perl Makefile.PL; make&lt;/code&gt; (or &lt;code&gt;perl Makefile.PL; sudo make&lt;/code&gt;) should do that trick.  This seemed like a good solution that could be a standard, but now I see that the &lt;a href="http://search.cpan.org/~adamk/Module-Install-0.99/lib/Module/Install/FAQ.pod#Do_I_really_have_to_avoid_auto_install()?"&gt;FAQ of that module&lt;/a&gt; says:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Do I really have to avoid auto_install()?&lt;br /&gt;&lt;br /&gt;auto_install() has a long history of breaking CPAN toolchains. Lots of people had a bad feeling on it, and have said it should be strongly avoided. In fact it was deprecated and removed once.&lt;br /&gt;&lt;br /&gt;Although most of the known problems have been fixed and you can use it more safely than ever, the use of auto_install() is still discouraged, especially if what you are writing is a module to be uploaded on the CPAN. auto_install() does lots of things itself, thus does not always do the same things as other toolchains do (including extra attribute handling, etc; which can be fixed somehow but that's not too DRY). It only supports CPAN and CPANPLUS as its backends. If you use other tools to install, it may still cause a trouble.&lt;br /&gt;&lt;br /&gt;Besides, now you can do what auto_install() does with other means. If your CPAN module is new enough, you can pass a dot to the cpan command it provides, and it will install all the required distributions from the CPAN:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ cpan .&lt;/code&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;So apparently this is the way to go - using the cpan shell.  There is a minor problem with this when used for testing - it would automatically install the package from the directory you are in. Sure you can suppress that you need by adding another command switch (-m), but it would be better if the default action was the safe one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3378928960117695179?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3378928960117695179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3378928960117695179' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3378928960117695179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3378928960117695179'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/06/installing-dependencies-for-your.html' title='Installing dependencies for your packaged for CPAN library'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3086143921375139979</id><published>2010-05-22T04:07:00.000-07:00</published><updated>2010-05-25T09:32:52.235-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Templates and inheritance</title><content type='html'>In every web site project I have been working on there inevitably came that moment that someone wanted to have a copy of the site with some small changes, or  that someone wanted to use a piece the website in something else.  In both cases it was all about (initially) some small changes, what they call as skin or a branded site.  With programming part we know what to do then - we design base classes for the core undifferentiated functionality and inherit from them in the targeted classes.  Most templating engines do have some notion of search path - so this should be doable with templates - but it always proves to be much more messy than it initially seems to be.  I'll try to catalogue here all the use cases and how they compare to the standard inheritance in object oriented programming languages and describe them in terms of operations on the search path.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;h4&gt;Initial setup&lt;/h4&gt;&lt;br /&gt;In 'normal' programming languages the atomic piece that can be inherited and overloaded and that is searched on the inheritance path is a method - in case of templates the atomic part is a whole template.  The granularity is defined differently, but we can do analogues things with both.  Here I will concentrate on the dispatching model familiar for users of most of the MVC frameworks with controllers and their methods as the endpoints (called actions). In this setting all the methods could have a matching template file and inheriting and overriding a template could work on the same level as inheriting and overriding an action.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Basic case&lt;/h4&gt;&lt;br /&gt;Lets say I have a controller 'MyApp::Controller::Book' with a few actions like 'view', 'list', 'edit' (a CRUD controller) and matching templates in 'templates/Book'.  I would like that when calling the render from that controller I did not need to specify the full path of the templates - but just call them by name 'view'. Also when they have a common subcomponents in the same directory they should be able to [% INCLUDE date_formatting %] them by name.  This is just like calling methods in a class and it can be accomplished by adding the 'templates/Book' directory at the start of the search path.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Library component&lt;/h4&gt;&lt;br /&gt;Sometimes we would like to use ready made components from some published library, maybe a CRUD controller for our Books.  We inherit from the library class in our 'MyApp::Controller::Book' and we would like its templates to be inherited in a similar way.  That means adding '/usr/lib/something/something/CRUD/templates' to our search path somewhere after 'templates/Book'.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Subclassing our own controllers&lt;/h4&gt;&lt;br /&gt;If our 'MyApp::Controller::Book' is a subclass of our own ''MyApp::Controller::Item' class - this is a very similar case to the above. Here as well we want to insert the search path of the parent class somewhere after 'templates/Book. But in this case what we insert is 'template/Item' - a path relative to our application root.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Application wide components&lt;/h4&gt;&lt;br /&gt;This is solved simply by adding an application wide element in the search path. It would be analogues to adding stuff to a common base class in standard programming - much more rare there.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Subclassing a whole site&lt;/h4&gt;&lt;br /&gt;This is the case of 'branded' sites where we would like to subclass everything at once.  It is maybe the most common case - but also the most difficult because there are no good analogies/solutions in standard object oriented programming.  If 'MyNewApp' inherits from 'MyApp' that does not automatically mean that 'MyNewApp::Controller::Book' springs to existence and can serve book information in the new app (but I've heard there are existing Object Oriented languages that work like that and some people are thinking about implementing this in Perl).  So I think we need to first think over how this is handled in the main framework and then we can deduce something about how to treat templates from that.  For the limited case of application wide components this can be solved by adding the new template root to the beginning of the search path - but it gets more complicated for all the other cases described above.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Conclusions&lt;/h4&gt;&lt;br /&gt;I mostly wrote that to have it all in one place - but I think it does show the need to make the template search path dependent on the controller used.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3086143921375139979?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3086143921375139979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3086143921375139979' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3086143921375139979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3086143921375139979'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/05/templates-and-inheritance.html' title='Templates and inheritance'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6469753953901101930</id><published>2010-05-19T14:43:00.001-07:00</published><updated>2010-05-20T14:31:15.646-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>A subject for mst's talk</title><content type='html'>I did not really intended to vote in that silly poll - but I think I have  found a subject for the talk that could be highly beneficial for the Perl community: &lt;a href="http://shadowcat.co.uk/blog/matt-s-trout/iron-man-lost?colour=whatever&amp;title=how+using+cognitive+science+and+what+else+I+am+going+to+make+html::zoom+actually+usable"&gt;How using the insights from cognitive science (and what else is needed) I am going to make HTML::Zoom actually usable for mere mortals&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6469753953901101930?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6469753953901101930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6469753953901101930' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6469753953901101930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6469753953901101930'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/05/subject-for-msts-talk.html' title='A subject for mst&apos;s talk'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-1403213879574528681</id><published>2010-05-18T13:10:00.001-07:00</published><updated>2010-05-18T14:47:09.427-07:00</updated><title type='text'>PSGI and Object Oriented Programming</title><content type='html'>There is one thing that seems pretty simple - but it took me a bit of mulling over to fully understand&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;a href="http://search.cpan.org/~miyagawa/PSGI-1.03/PSGI.pod#SPECIFICATION"&gt;A PSGI application is a Perl code reference.&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;It is a reference to a sub that expects a hash ref representing the HTTP request passed to it as the one and only parameter and which returns an array ref representing a HTTP response.   Hmm - yeah that's what web apps do - take the request and return the response.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But then you think - OK, but I like Object Oriented code and I want my application to be an object with attributes and stuff - so what can I do?  Well - that is simple. Have your app as object as you like, and to the PSGI layer pass a closure referring to that object.  For example if you application object normally handles the requests with a &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;-&gt;handle&lt;/span&gt; method then&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;script src="http://gist.github.com/405602.js?file=psgi_closure.pl"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;would return a suitable callback.  Which you can then use in your app.psgi file:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="http://gist.github.com/405604.js?file=app.psgi.pl"&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;And this is exactly what I do in &lt;a href="http://github.com/zby/WebNano"&gt;WebNano&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-1403213879574528681?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/1403213879574528681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=1403213879574528681' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1403213879574528681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1403213879574528681'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/05/psgi-and-object-oriented-programming.html' title='PSGI and Object Oriented Programming'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-2145151745497689637</id><published>2010-05-12T11:15:00.000-07:00</published><updated>2010-05-12T11:17:43.994-07:00</updated><title type='text'>Web Applications and Dispatching</title><content type='html'>Historically the operation of  finding the code to handle the web request was trivial - the server just matched the path part of the web request into the filesystem to find the CGI program producing the requested page.  But then it got more complicated when we moved from the CGI 'one program equals one page' way into the realm of web applications that serve many pages.&lt;br /&gt;&lt;br /&gt;The tree (or DAG) data structure is the underlying concept of both the path part of URL and many programming language library (or class) structures - so there is a natural way of mapping between them.  To have code handling requests to related pages in the same file we can extend it so that the last part of the path is interpreted as a subroutine name.&lt;br /&gt;&lt;br /&gt;That idea gets a bit more complicated when we realize that we don't want to expose all of our often internal methods (and libraries/classes) to be callable from outside - we need a way to mark them as 'external' and expose only these.  &lt;br /&gt;&lt;br /&gt;Of course sometimes there are reasons that we don't want to use such a literal mapping, it can be some security (by obscurity) need to hide internal code structures, need for more elegant URLs or other requirements.  So sometimes we need to extend it or completely replace it with something else.&lt;br /&gt;&lt;br /&gt;The Perl web frameworks (that I know the best) in respect to usage of that mapping can be roughly divided into following styles (many use more than one style so the boundaries are fuzzy):&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt; The 'old' CGI (or PHP) paradigm of one address one program&lt;br /&gt;&lt;br /&gt;&lt;li&gt; Using the mapping of paths to libraries, selecting 'externally callable' methods by placing them on a list ( run_modes in CGI::Aplication ).&lt;br /&gt;&lt;br /&gt;&lt;li&gt; Using the mapping of paths to libraries, but dispatching to methods configured via a hash (also run_modes in CGI::Application).&lt;br /&gt;&lt;br /&gt;&lt;li&gt; Using the mapping of paths to libraries (but not to methods) and calling the 'get' or 'post' method in the landing library (like in Tatsumaki).&lt;br /&gt;&lt;br /&gt;&lt;li&gt; Configuring the dispatching by code attributes of the methods (like in Catalyst).&lt;br /&gt;&lt;br /&gt;&lt;li&gt; Not using methods but anonymous subroutines.  This way it is easy to assign the dispatching configuration to the code by using DSLs (like in Dancer).&lt;br /&gt;&lt;br /&gt;&lt;li&gt; Dispatching configuration external to the classes that are dispatched to.&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Having the dispatching configuration close to the subroutine code let's you avoid switching between two places in the source code when adding a new action or changing an existing one.  I think one of the greatest conveniences of Catalyst was that that configuration was not only in the same file but directly in the subroutine definition.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-2145151745497689637?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/2145151745497689637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=2145151745497689637' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2145151745497689637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2145151745497689637'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/05/web-applications-and-dispatching.html' title='Web Applications and Dispatching'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-8714519386840428760</id><published>2010-04-17T01:07:00.000-07:00</published><updated>2010-04-18T00:21:59.605-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>WebNano - what I did not say at the London.pm tech meeting</title><content type='html'>About a month ago I had a presentation at the London.pm tech meeting about the design ideas I plan to experiment in &lt;a href="http://github.com/zby/WebNano"&gt;WebNano&lt;/a&gt;.  There are a few things that I did not have time to tell - and I plan to blog about them.  First of all I think I should have admitted that I stole the both the name and the idea from Simon Cozen's &lt;a href="http://github.com/simoncozens/canary/blob/master/lib/MicroMaypole.pm"&gt;MicroMaypole&lt;/a&gt; (I hope he will treat that in the terms of the well known quote about imitation and not intellectual property trespassing:).  &lt;br /&gt;&lt;br /&gt;At the presentation I mentioned that there is not much code in WebNano currently - but maybe this was not the best way to put it. I actually don't plan to ever have much code in it and the example of MicroMaypole shows that perhaps such a minimal web framework can be a practical thing, but I do plan to build some more examples using that minimal code so that I can be sure that even if minimal it does have all the desired features.  What are those features will be the subject of other blog posts soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-8714519386840428760?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/8714519386840428760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=8714519386840428760' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8714519386840428760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8714519386840428760'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/04/webnano-what-i-did-not-say-at-londonpm.html' title='WebNano - what I did not say at the London.pm tech meeting'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-4694538611716041080</id><published>2010-02-01T06:59:00.001-08:00</published><updated>2010-02-06T09:33:30.594-08:00</updated><title type='text'>Frameworks are framing, libraries are liberating</title><content type='html'>It seems that the season is &lt;a href="http://mojolicious.org/"&gt;open&lt;/a&gt; &lt;a href="http://github.com/zby/WebNano"&gt;and everyone&lt;/a&gt; &lt;a href="http://search.cpan.org/%7Ecavac/Maplat-0.97/lib/Maplat/Web.pm"&gt;is&lt;/a&gt; &lt;a href="http://github.com/stevan/OX"&gt;writing&lt;/a&gt; &lt;a href="http://github.com/stevan/OX"&gt;his new&lt;/a&gt; &lt;a href="http://dancer.sukria.net/"&gt;web framework&lt;/a&gt;  &lt;a href="http://www.shadowcat.co.uk/blog/matt-s-trout/introducing-web-simple/"&gt;again&lt;/a&gt; (all authors of the dozens of other recently created Perl web framework - please accept my apologies - I could not possibly link to all of your babies).  If you ask me why is that? My answer is: it is easy now.  We have libraries that do nearly everything that the traditional web frameworks provide.  You don't need to write much - you just saw together the available patches and voila: your own web framework. You can be proud.&lt;br /&gt;&lt;br /&gt;For some time I was thinking: OK, so now we have that cambrian explosion of new frameworks, that's OK, it will all settle down, people will select the best of them and the rest will die off. All we need to do is waiting. We could also speed it up a bit and make it a bit more smooth and rational by learning how to evaluate the frameworks. To do that we need to talk about them, study their functions and compare designs, project goals, project management styles and all of that. This will not be easy, but once we get past the awsome depth of common analyses of the 'this sucks' style and start to think about 'this is good for that and that other thing is better if you need something else', the rest will be incremental.&lt;br /&gt;&lt;br /&gt;And I still believe that we need to talk more about design solutions and expand our vocabulary and use less of 'this is stupid' authoritative evaluations. This is something beneficial in any circumstances. But now I also think that since we have the libraries that do the all the work that previously was done by frameworks - then why should we build any more frameworks? Frameworks are coupling, they tie together the libraries that do the actual work and send that loose, uncohesive package to the programmer, who he has no choice, but has to use all of it and in the way prescribed by the framework. But every educated programmer knows that coupling is bad and cohesion is good. So why don't we just use the available nicely decoupled and internally cohesive libraries instead? Yeah, the libraries don't yet do all the 100% of stuff traditionally provided by frameworks, they can do 80% or even 90% of it but not yet the whole 100%, it is still ahead of us to extract the other 10% of functionality from the existing frameworks and turn it into a nicely decoupled and internally cohesive libraries.&lt;br /&gt;&lt;br /&gt;Historically the trend is clear - the first frameworks did everything, the MVC frameworks included all Model, View and Controller components, then came Catalyst which is mostly just the Controller part. But that was not the end of decoupling - the Controller part still can be broken down further. And it was, with libraries like HTML::Engine budding off it, splitting and heading for an independent CPAN life. Now it is time to have a look at Catalyst and other frameworks and think what are the exclusive features that it provides that are not yet available as independent CPAN libraries. We have &lt;a href="http://search.cpan.org/dist/Plack "&gt;Plack&lt;/a&gt;, that provides all the abstraction needed for easy deployment and &lt;a href="http://advent.plackperl.org/2009/12/day-13-use-placktest-to-test-your-application.html"&gt;testing&lt;/a&gt;, we have packages like &lt;a href="http://advent.plackperl.org/2009/12/day-13-use-placktest-to-test-your-application.html"&gt;Bread::Board&lt;/a&gt; that provide a generic way of initialising application components, and I am sure there are also other interesting libraries at CPAN that provide other parts of the framework functionality. So what is left?&lt;br /&gt;&lt;br /&gt;Maybe I am missing something, but the only important functionality of Catalyst that I cannot find any generic libs for is dispatching - selecting the subroutine (or method) that will handle a given HTTP request.  I don't see any reasons why this should be hard to do. In fact I have already started working on that. OK - to be frank, what I started to work on was another web framework. I decided that I would like to have a mini framework and started coding it. Only now, after having the first CRUD example written in it, I can see that all I wrote is just a dispatch system, the other parts are freely available at CPAN.  I can use Plack for the web engine abstraction and Plack::Test for testing, I can use Bread::Board for application components creation and Moose as the object framework - no need to reinvent the wheel.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-4694538611716041080?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/4694538611716041080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=4694538611716041080' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4694538611716041080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4694538611716041080'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/02/frameworks-are-framing-libraries-are.html' title='Frameworks are framing, libraries are liberating'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-1023148338423743553</id><published>2010-01-13T02:51:00.000-08:00</published><updated>2010-01-13T08:17:46.837-08:00</updated><title type='text'>MST explains the ideas lying behind his 'being a bastard'</title><content type='html'>It always seemed a bit weird when I saw mst kick himself out of an IRC channel - now &lt;a href="http://www.shadowcat.co.uk/blog/matt-s-trout/on-being-a-bastard/"&gt;we have it all nicely explained&lt;/a&gt;.  Next time we'll have a self tickling machine, I am sure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-1023148338423743553?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/1023148338423743553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=1023148338423743553' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1023148338423743553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1023148338423743553'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2010/01/mst-explains-ideas-lying-behind-his.html' title='MST explains the ideas lying behind his &apos;being a bastard&apos;'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-9213075893666879525</id><published>2009-12-30T00:57:00.000-08:00</published><updated>2009-12-30T02:34:12.333-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Bread::Board</title><content type='html'>Lots of packages in the Catalyst namespace are simple adaptors of external libraries.  In many cases what you need from that adaptor layer is only passing initialisation values from the config file to the appropriate call to the object creator.  By using the &lt;a href="http://martinfowler.com/articles/injection.html"&gt;Dependency Injection&lt;/a&gt; pattern you can move that initialisation code out of that "deep in the framework guts" place into something that can be called another config file - containing values that are complex objects instead of simple constants.  This way your view object can be constructed there and then injected into the application which does not need to know how to construct it.  You still might prefer to have a different config file with simple literal configuration values using the standard YAML or Config::General syntax.&lt;br /&gt;&lt;br /&gt;If that was too vague for you - don't worry - Stevan promised some more docs for &lt;a href="http://search.cpan.org/~stevan/Bread-Board/lib/Bread/Board.pm"&gt;Bread::Board&lt;/a&gt; soon.  The real take away from all of this is that Bread::Board and future sub-classes of it spares you from the need to writing adaptor classes for all the view or model classes of your yet another web framework.  Maybe you'll not need a framework at all - and assemble your application using Bread::Board out of a web dispatcher and other ready made parts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-9213075893666879525?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/9213075893666879525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=9213075893666879525' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/9213075893666879525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/9213075893666879525'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/12/breadboard.html' title='Bread::Board'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-4652608578918854701</id><published>2009-12-23T23:06:00.000-08:00</published><updated>2009-12-24T02:33:29.054-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Frameworks are not yet well refactored libraries.</title><content type='html'>At first we had Catalyst.  After some refactoring we got HTTP::Engine and now we have &lt;a href="http://plackperl.org/"&gt;PSGI/Plack&lt;/a&gt; and the tools around that abstraction that provide a lot of functionality that previously required using Catalyst.  Now all of that is in libraries that &lt;a href="http://blog.urth.org/2009/11/want-good-tools-break-your-problems-down.html"&gt;can be used independently from each other&lt;/a&gt;, there is no coupling between the components other than the well defined and pretty minimal PSGI interface.&lt;br /&gt;&lt;br /&gt;The title of this blog post might not be universally true, it is possible that there are some kernel parts in some frameworks or even most of the frameworks that could never be in any practical way reduced into sets of libraries.  But what I observe is that frameworks tend to grow and only in very exceptional cases spawn libraries that are refactored out of their main body.  It is just so much easier to just write new extensions, plugins or things that use the whole framework than find the right abstraction that would let to split some functionality out of the main code base.  Certainly I would never guess that the simple PSGI abstraction would let people refactor so much into separate libraries, I bow to it's author.  But we should always try:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Antoine de Saint-Exupery&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-4652608578918854701?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/4652608578918854701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=4652608578918854701' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4652608578918854701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/4652608578918854701'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/12/frameworks-are-not-yet-well-refactored.html' title='Frameworks are not yet well refactored libraries.'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-7383091592921632925</id><published>2009-12-18T09:37:00.000-08:00</published><updated>2009-12-18T09:52:04.264-08:00</updated><title type='text'>Catalyst app/context split</title><content type='html'>This week I've received a bounty from the &lt;a href="http://www.enlightenedperl.org/"&gt;Enlightened Perl Organisation&lt;/a&gt; for my work on the &lt;a href="http://dev.catalystframework.org/repos/Catalyst/Catalyst-Runtime/5.80/branches/basic-app-ctx-separation-cleaned/"&gt;app/context split&lt;/a&gt;.  As I understand they have doubled the private bounty from groditi who was too busy to keep his promise to do that job and wanted someone to free him from the shame of broken promises.  Anyway I am very happy with the outcome.  I am not sure if this can be a stable way of founding work on Open Source projects - but it this time it worked :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-7383091592921632925?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/7383091592921632925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=7383091592921632925' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/7383091592921632925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/7383091592921632925'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/12/catalyst-appcontext-split.html' title='Catalyst app/context split'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-9072477185517278431</id><published>2009-12-10T15:06:00.000-08:00</published><updated>2009-12-10T15:15:42.283-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Scope and Immutability</title><content type='html'>I am sold on &lt;a href="http://blog.woobling.org/2009/05/immutable-data-structures.html"&gt;the immutability thing&lt;/a&gt;.  I started to think about various designs and about what immutability of objects would mean to them and I think the results are promising - they tend to have much more clear structure - and just thinking about immutability gives you a chance to see an additional structure in the code.  One quite obvious rule of such design is that you cannot keep data of narrower scope in objects with wider scope - and this forces you to think about the scope of various data pieces in your programs.  For example in web oriented programming you have (usually) three scopes:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Application - i.e. all data that is persistent to the whole web server process (like configuration)&lt;br /&gt;&lt;li&gt;Session - i.e. data saved into the session variables (there is an opinion, and I mostly subscribe to it, that you should keep that minimal).&lt;br /&gt;&lt;li&gt;Request - i.e. the data you receive from the web client and that you send back to it&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;An example of framework that does not respect this division is known to everyone - it's Catalyst - fortunately &lt;a href="http://dev.catalystframework.org/repos/Catalyst/Catalyst-Runtime/5.80/branches/basic-app-ctx-separation-cleaned/"&gt;the app/context split is mostly done&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Acknowledgements: Stevan thanks for the web apps scope break down :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-9072477185517278431?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/9072477185517278431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=9072477185517278431' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/9072477185517278431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/9072477185517278431'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/12/scope-and-immutability.html' title='Scope and Immutability'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3488232952864171981</id><published>2009-12-05T02:29:00.000-08:00</published><updated>2009-12-05T03:29:20.252-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>External dependencies once again</title><content type='html'>My &lt;a href="http://www.mail-archive.com/cpan-workers@perl.org/msg00521.html"&gt;proposal to add a 'lib_requires' keyword to the META file - with identical semantics as Devel::CheckLib&lt;/a&gt; did not make at this round of META spec changes.  Now I think that maybe a better strategy would be to start with adding this to the documentation.  I am sure many packages already do that - but I have encountered others that don't.  What I have in mind is a standard POD section that would be generated by all the module scaffolding generators (like &lt;a href="http://search.cpan.org/~petdance/Module-Starter/lib/Module/Starter.pm"&gt;Module::Starter&lt;/a&gt;) and which would contain all the information needed to install the external lib in common environments.  After this becomes a common thing we would be able to make more informed decisions about including it into the META file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3488232952864171981?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3488232952864171981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3488232952864171981' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3488232952864171981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3488232952864171981'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/12/external-dependencies-once-again.html' title='External dependencies once again'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-8164920762847953974</id><published>2009-11-28T02:08:00.000-08:00</published><updated>2009-11-28T03:31:46.000-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Warszawa.pm - Biblioteczka (The Library)</title><content type='html'>W czwartek odbyło się spotkanie Warszawa.pm.  Warta zanotowania jest inauguracja naszej biblioteczki - pożyczyłem od Piotrka &lt;a href="http://en.wikipedia.org/wiki/Peopleware:_Productive_Projects_and_Teams"&gt;Czynnik Ludzki&lt;/a&gt;. Dzięki!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Last Thursday there was a Warszawa.pm meeting.  Worth noting is the inauguration of our library - Piotrek lended &lt;a href="http://en.wikipedia.org/wiki/Peopleware:_Productive_Projects_and_Teams"&gt;Peopleware: Productive Projects and Teams&lt;/a&gt; to me. Thanks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-8164920762847953974?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/8164920762847953974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=8164920762847953974' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8164920762847953974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8164920762847953974'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/11/warszawapm-biblioteczka-library.html' title='Warszawa.pm - Biblioteczka (The Library)'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-8044525186423941393</id><published>2009-11-20T11:03:00.000-08:00</published><updated>2009-11-20T11:15:54.400-08:00</updated><title type='text'>What are the features that Perl shares with Lisp?</title><content type='html'>The author of the famous &lt;a href="http://hop.perl.plover.com/book/"&gt;Higher-Order Perl&lt;/a&gt; book (it's available for free download - so no excuse for those that have not yet read it) writes: &lt;blockquote&gt;&lt;br /&gt;Perl is much more like Lisp than it is like C. If you pick up a good&lt;br /&gt;book about Lisp, there will be a section that describes Lisp’s good features. For example, the book Paradigms of Artificial Intelligence Programming, by Peter Norvig, includes a section titled What Makes Lisp Different? that describes seven features of Lisp. Perl shares six of these features; C shares none of them. These are big, important features, features like first-class functions, dynamic access to the symbol table, and automatic storage management.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Dear lazy web: what are the other three features?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-8044525186423941393?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/8044525186423941393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=8044525186423941393' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8044525186423941393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8044525186423941393'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/11/what-are-features-that-perl-shares-with.html' title='What are the features that Perl shares with Lisp?'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-8273427875353245466</id><published>2009-11-14T13:06:00.000-08:00</published><updated>2009-11-14T13:16:56.355-08:00</updated><title type='text'>On naming things</title><content type='html'>One benefit that I have hope will be the result of the IronMan blogging challenge is that Perl people will get more expressive in describing their design.  What I can see now is that often there is a strong belief that some code has a good or bad design but any inquiry into why said design is good or bad ends in a 'because you are stupid and you don't understand' argument.  While I agree that coding can be sometimes more productive than discussing, I think this rule should not be treated absolutely.  All design is trading one thing for another one, having this trade-off stated explicitly gives us the power to weight it intelligently and appropriately to circumstances.  In contrast an unnamed intuition can be only an article of our faith in the designers skills.&lt;br /&gt;&lt;br /&gt;There is power in naming things as the popularity of Design Patterns shows.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-8273427875353245466?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/8273427875353245466/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=8273427875353245466' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8273427875353245466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8273427875353245466'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/11/on-naming-things.html' title='On naming things'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-2253498493018013595</id><published>2009-11-11T14:16:00.000-08:00</published><updated>2009-11-11T14:36:48.355-08:00</updated><title type='text'>Stuff</title><content type='html'>Only remotely related to Perl.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Socio-Technical Systems&lt;/h3&gt;&lt;br /&gt;I like the definition from &lt;a href="http://brianwhitworth.com/STS/STS-chapter1.pdf"&gt; The Social Requirements of Technical Systems&lt;/a&gt;, now I have what CPAN realy is.  I have not yet read the whole &lt;a href="http://brianwhitworth.com/STS/"&gt;Handbook of Research on Socio-Technical Design and Social Networking Systems&lt;/a&gt; but the rest seems rather dissapointing.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;von Hippel&lt;/h3&gt;&lt;br /&gt;I recently discovered that most of his work is available on-line: &lt;a href="http://web.mit.edu/evhippel/www/papers.htm"&gt;Collected Papers&lt;/a&gt;, &lt;a href="http://web.mit.edu/evhippel/www/books.htm"&gt;Downloadable Books&lt;/a&gt;.  I recommend it to people trying to understand Open Source. He is much more 'technical' than Yochai Benkler.  I've just finished reading &lt;a href="http://web.mit.edu/evhippel/www/papers/Private-Collective%20Model%20OS.pdf"&gt;Open Source Software and the 'Private-Collective' Innovation Model&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Rene Girard&lt;/h3&gt;&lt;br /&gt;I am working on a paper about on-line conflict in the light of mimetic theory.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-2253498493018013595?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/2253498493018013595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=2253498493018013595' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2253498493018013595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2253498493018013595'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/11/stuff.html' title='Stuff'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-5548027370827281531</id><published>2009-11-03T08:47:00.000-08:00</published><updated>2009-11-03T11:57:00.473-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Role that adds Traits to multiple classes</title><content type='html'>The DBIC model stuff naturally spans the whole FormHandler class tree - there are things that need to be added to the main form class, but also to the Field classes.  An obvious example of the latter is the &lt;code&gt;lookup_options&lt;/code&gt; method which loads data from the db table (ResultSet object more precisely) appropriate for the field into the field's options array.  It does not really touch any global form stuff and:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$field-&gt;form-&gt;lookup_options( $field, ... )&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;is like reaching with your left hand to your right pocket.  I mean really awkward.  So what we need is a form role that would add other roles to the fields classes. I imagined that this could be possible, in theory a role could be a hierarchy that would be applied to a class hierarchy - but I don't think you can do that  with current Moose, so instead I used a hook in the method that builds fields and added there code to inject an appropriate Trait.&lt;br /&gt;&lt;br /&gt;The code is in new branches &lt;a href="http://github.com/gshank/html-formhandler/tree/traits_for_models"&gt;in the main HTML::FormHandler repo&lt;/a&gt; and in the &lt;a href="http://github.com/gshank/html-formhandler-model-dbic/tree/traits_for_models"&gt;HTML::FormHandler::Model::DBIC repo&lt;/a&gt;.  I am waiting for commetns.  I would think that this is not something unusual - so I guess others must have already solved similar problems before - I would like to hear what they did.&lt;br /&gt;&lt;br /&gt;We have a similar problem with rendering. It is a role now so that it can be easily replaced, but it is naturally recursive, fields should know how to render themselves so we need a way to apply a whole set of roles in one sweep to the whole form class structure.  It looks like there really is some abstract super-role in there.&lt;br /&gt;How much is it monkey patching, how much is it action at a distance?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-5548027370827281531?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/5548027370827281531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=5548027370827281531' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/5548027370827281531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/5548027370827281531'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/11/role-that-adds-traits-to-multiple.html' title='Role that adds Traits to multiple classes'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-2477947952397854966</id><published>2009-10-27T22:57:00.000-07:00</published><updated>2009-10-27T23:53:50.354-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Controller immutability</title><content type='html'>On IRC I've got an answer from t0m and others about why they would not use controller attributes for storing data related to the current request - they want to keep their controller object immutable for the request phase.  The idea is that if you have an object that is being reused then it would be nice if after each use of that object it is still in the same clean state.  That is it is nice to always have the changes contained in a minimal area. &lt;br /&gt;&lt;br /&gt;I'll leave it to the &lt;a href="http://blog.woobling.org/2009/05/immutable-data-structures.html"&gt;experts&lt;/a&gt; to list all the advantages of immutable data structures, but I've seen why we needed a similar compartmentalisation in HTML::FormHandler.  The FormHandler form object is reusable, you can use it to validate many parameter hashes. We started coding it as a mutable object and storing all the changing values in the form object itself, the first problem was that we kept forgetting to reset them at the start of processing of new data.  This lead to many subtle bugs, sometimes difficult to track so we started to just recreate the form object for each processing run. This worked OK, because the form object itself was not that heavy to create until someone had a form object that contained other heavy object and recreating it would require recreating them.  So eventually we separated all the state that changes during the processing into a separate &lt;code&gt;Result&lt;/code&gt; object, now to clean the form state we need to recreate only that separate object.&lt;br /&gt;&lt;br /&gt;It needs to be stated clearly that this separation of immutability is a trade-off (as always) - it is an additional requirement so it increases the complexity of the code and means for example that the &lt;code&gt;$self&lt;/code&gt; object in controller actions is underused - because actions should not change it's state (including storing something in it's attributes).  Certainly it is not feasible to make such change now and this also would be a trade-off but for the sake of exercising imagination: maybe actions could be methods on the changing part (and not on the controller object) and only use the controller object in some way - this way all the basic code (like that from the Manual) would use &lt;code&gt;$self&lt;/code&gt; object in the way common to object oriented code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-2477947952397854966?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/2477947952397854966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=2477947952397854966' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2477947952397854966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/2477947952397854966'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/10/controller-immutability.html' title='Controller immutability'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6317382570751554534</id><published>2009-10-24T02:14:00.000-07:00</published><updated>2009-10-24T04:20:23.853-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Catalyst::Component::InstancePerContext</title><content type='html'>How often do you use the controller object?  It is the first, most important parameter passed to all the controller methods - but it is nearly never used in the body of these methods.  In the code samples in the whole Catalyst::Manual distribution $self is assigned to 117 times - but is used only 38 times (and not all code samples are controllers there).  This sounds like a strange case for object oriented code which bases it's definition on the usage of the $self object.&lt;br /&gt;&lt;br /&gt;There is &lt;a href="http://jjnapiorkowski.vox.com/library/post/does-anyone-else-hate-the-stash.html"&gt;much discussion about the stash and how to replace it&lt;/a&gt;.  The main problem with stash is that it is global - there is no use in replacing it with another global thing.  Just like global variables it needs to be replaced by many specialized local things like parameter passing and attributes, the controller object attributes, and for that to be entirely clean we need the a new controller object per response.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6317382570751554534?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6317382570751554534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6317382570751554534' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6317382570751554534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6317382570751554534'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/10/catalystcomponentinstancepercontext.html' title='Catalyst::Component::InstancePerContext'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-9174358260410629263</id><published>2009-10-21T02:06:00.000-07:00</published><updated>2009-10-21T02:18:21.517-07:00</updated><title type='text'>OpenID support in LoginSimple</title><content type='html'>This week I've added some OpenID support to &lt;a href="http://github.com/bobtfish/catalystx-simplelogin"&gt;LoginSimple&lt;/a&gt;.  Please clone the git repository and try it out!  The hard part of the whole LoginSimple idea is to make it universal enough. We need people to try to apply it in many different scenarios and give us some feedback.&lt;br /&gt;&lt;br /&gt;The test application is in &lt;code&gt;t/lib/TestAppOpenID.pm&lt;/code&gt;, it has some tests in &lt;code&gt;t/07-openid-live.t&lt;/code&gt;, but you can also run it with &lt;code&gt;perl -Ilib t/lib/script/testappopenid_server.pl&lt;/code&gt; and then go to the &lt;code&gt;http://localhost:3000/login&lt;/code&gt; page and test it manually.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-9174358260410629263?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/9174358260410629263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=9174358260410629263' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/9174358260410629263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/9174358260410629263'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/10/openid-support-in-loginsimple.html' title='OpenID support in LoginSimple'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6446023754672036777</id><published>2009-10-13T04:35:00.000-07:00</published><updated>2009-10-14T23:12:50.362-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>HTML::FormHandler - a few notes</title><content type='html'>This is not an  &lt;a href="http://search.cpan.org/~gshank/HTML-FormHandler-0.28001/lib/HTML/FormHandler/Manual/Intro.pod"&gt;introduction to HTML::FormHandler&lt;/a&gt; - the docs there are very good, but I wanted to write down the main ideas I had when contributing to the design of it.&lt;br /&gt; &lt;br /&gt;Let's look at the functions of a &lt;a href="http://www.perlfoundation.org/perl5/index.cgi?form_processing"&gt;form processor&lt;/a&gt;:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;processing the input into internal representation&lt;br /&gt;&lt;li&gt;checking the values&lt;br /&gt;&lt;li&gt;saving the internal representation into the persistence layer and loading values from it&lt;br /&gt;&lt;li&gt;rendering the form (with input, error messages, etc)&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;The 'best practice' of rendering the HTML view of an application page is to do it in the templates.  Unfortunately there is just too much logic needed for the correct rendering of forms (mostly with the display of errors) to leave that for the templates mini language (like that of TT) - that's why this needs to be done by the form processor.  But because of the diversity of the rendering requirements it also needs to be easily replaceable, ideally part by part. Then the application could start with a crude but working HTML rendering, introduced with minimal effort from the programmer since it is built into the processor and later gradually refined and replaced.  &lt;br /&gt;&lt;br /&gt;CGI.pm and after it Catalyst and other libraries parse the url-encoded and body parameters into a hash of scalar values but internally we would like to manipulate objects like DateTime instead of lists of values for year, month and day.  In HFH this conversion is done in two phases - first the input is turn into a deeper structure built of hashes and arrays - then then the processor goes recursively from the leaves and at each node applies a conversion if it is defined for that node.  &lt;br /&gt;&lt;br /&gt;There is always a question when we should do the checks - sometimes it is easier do do them on the input data sometimes on the internal values.  A good example is DateTime - we can check if the day field is a number between 1 and 31, but we also need to check if the whole date is correct and the business rules could add another requirement that the day of the week is Monday or some other operation that is most convenient on the DateTime object.  In FormHandler all of this is possible: &lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/209482.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;How this works?  As explained above the processor starts with the leave nodes - and checks the &lt;code&gt;day&lt;/code&gt;, &lt;/code&gt;month&lt;/code&gt; and &lt;code&gt;year&lt;/code&gt; fields (here they don't define any transformations only checks, but they could).  Then it goes to the parent node &lt;code&gt;date_time&lt;/code&gt; and there it has the hash of values from the leave nodes ready for the next transformation and checks - it is passed to:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;sub { DateTime-&gt;new( shift ) }&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If that subroutine triggers an exception, for example when someone passes &lt;br /&gt;&lt;br /&gt;&lt;code&gt;{ year =&gt; 2009, month =&gt; 2, day =&gt; 30 }&lt;/code&gt; &lt;br /&gt;&lt;br /&gt;to it - then the error is recorded with the message &lt;i&gt;This is not a correct date&lt;/i&gt;.  If it works - the value returned from it, a DateTime object, is then passed to the next check, and later presumably saved to the database.  The checks and transformations are taken from a single list - so you can interweave them as you need.&lt;br /&gt;Instead of &lt;code&gt;transform&lt;/code&gt; and &lt;code&gt;check&lt;/code&gt; in the &lt;code&gt;apply&lt;/code&gt; attribute we can also use the Moose types and coercions and also we can mix these two styles (for example coerce some value using Moose types and then check it again).  If someone needs even more power - he can also write &lt;a href="http://search.cpan.org/~gshank/HTML-FormHandler-0.28001/lib/HTML/FormHandler/Manual/Intro.pod#Creating_custom_fields"&gt;his own field class with it's own validation method&lt;/a&gt; - and do both validation and transformations in there, that method would receive the same hash of child values.&lt;br /&gt;&lt;br /&gt;To save the full data structure of values that can contain many inter-related records &lt;code&gt;HTML::FormHandler::Model::DBIC&lt;/code&gt; uses&lt;br /&gt;&lt;a href="http://search.cpan.org/~zby/DBIx-Class-ResultSet-RecursiveUpdate/lib/DBIx/Class/ResultSet/RecursiveUpdate.pm"&gt;&lt;code&gt;DBIx::Class::ResultSet::RecursiveUpdate&lt;/code&gt;&lt;/a&gt;.  I separated it so that HFH is not related to the hacks I made there :)  Or maybe I hoped that perhaps other form processors could reuse my module.  Using it you can update a company record together with all it's related addresses in one form.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6446023754672036777?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6446023754672036777/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6446023754672036777' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6446023754672036777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6446023754672036777'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/10/htmlformhandler-few-notes.html' title='HTML::FormHandler - a few notes'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-116761801565475455</id><published>2009-10-07T10:27:00.000-07:00</published><updated>2009-10-10T00:24:59.643-07:00</updated><title type='text'>Barriers to entry</title><content type='html'>Chromatic calls us to &lt;a href="http://www.modernperlbooks.com/mt/2009/10/remove-the-little-pessimizations.html"&gt;Remove the Little Pessimizations&lt;/a&gt;, to &lt;i&gt;sand off the tiny, rough corners of our software that individually are small, ignorable distractions&lt;/i&gt;.  I've read somewhere that each barrier to entry reduces the number of users by some percent - and it is a good model to think about it.  Each one reduces the number of possible uses and users and the effect is cumulative - hundreds of small barriers make the tool useful in only a narrow niche, but even just one small barrier can make a tool not usable in a particular setting.  The question is when fixing these little pessimizations becomes &lt;a href="https://www.blogger.com/comment.g?blogID=36345871&amp;postID=5571112833858026197"&gt;needlesly pedantic&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I believe that fixing CPAN installation issues, each one usually a small issue occurring in some special cases is needed (at least for the most popular modules) if we don't want to confine CPAN users, and since CPAN is the killer application of Perl, then it follows that also Perl users, to a narrow niche.  &lt;br /&gt;&lt;br /&gt;Another thing is how off-putting are the pessimizations that seem gratuitous, you immediately feel neglected and you imagine how the arrogant developers just don't care about your case.  Then there are also pessimizations that look small if you have a big project - but are impenetrable barriers for small projects - this is how Perl lost the place of the most used language for WWW programming to PHP.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-116761801565475455?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/116761801565475455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=116761801565475455' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/116761801565475455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/116761801565475455'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/10/barriers-to-entry.html' title='Barriers to entry'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-1770132420310229244</id><published>2009-10-06T07:11:00.000-07:00</published><updated>2009-10-06T09:54:21.507-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>CPANHQ</title><content type='html'>There is a project to build a Catalyst based CPAN search engine, with the idea to make it more hackable and ultimately incorporate some more 'social' features into it. The original effort was started by Brian Cassidy, he created a &lt;a href="http://github.com/bricas/cpanhq"&gt;cpanhq github repository&lt;/a&gt; and wrote some initial code, later there were some features added by Shlomi Fish (in his &lt;a href="http://github.com/shlomif/cpanhq"&gt;repo&lt;/a&gt;) and now I am working on it.  In &lt;a href="http://github.com/zby/cpanhq"&gt;my repo&lt;/a&gt; you'll find a version that finally has a search page and it even works.  It uses the SQLite FTS3 full text search engine.&lt;br /&gt;&lt;br /&gt;The biggest problem for me is that I had to modify the database quite extensively and now the loading scripts don't work any longer.  To show something I decided to load the database into the repo - so now it can take awful long time to download the software, but in return right after the download you should be able to try out the searching.  It is not at end user quality - you need to know some internals to use if effectively (like using 'me.name desc' in the order field to sort the packages by name), but it should be reasonably fast.  Now I am thinking what are the most useful search strategies.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-1770132420310229244?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/1770132420310229244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=1770132420310229244' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1770132420310229244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1770132420310229244'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/10/cpanhq.html' title='CPANHQ'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-1996577897085088036</id><published>2009-09-29T00:03:00.000-07:00</published><updated>2009-09-29T00:26:09.323-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>warszawa.pm</title><content type='html'>Witam,&lt;br /&gt;&lt;br /&gt;Co prawda zwykle piszę tutaj w języku angielskim - ale reklamówkę naszej grupy Perl Mongers postanowiłem napisać po polsku, żeby było widać, że u nas też się coś dzieje.  Mamy już swoją wiki: &lt;a href="http://warszawa.pm.org/"&gt;http://warszawa.pm.org/&lt;/a&gt;.  Jeszcze nie wszystko działa, ale miejmy nadzieję, że administrator sie postara i naprawi.  Żeby dostać konto na wiki trzeba poprosić na &lt;a href="http://warszawa.pm.org/"&gt;liście dyskusyjnej&lt;/a&gt;, niestety ze względu na spam nie mogliśmy wiki zrobić zupełnie otwartej.  Zapraszamy na wiki, listę i spotkania.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-1996577897085088036?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/1996577897085088036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=1996577897085088036' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1996577897085088036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1996577897085088036'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/09/warszawapm.html' title='warszawa.pm'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-5571112833858026197</id><published>2009-09-22T01:00:00.000-07:00</published><updated>2009-09-22T05:15:56.372-07:00</updated><title type='text'>Optional Dependencies Are Going Out of Fashion</title><content type='html'>I was reading the &lt;a href="http://cpansearch.perl.org/src/RIBASUSHI/DBIx-Class-0.08112/Changes"&gt;Changes&lt;/a&gt; document for the latest DBIC release and I spotted:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;- Remove the recommends from Makefile.PL, DBIx::Class is not&lt;br /&gt;          supposed to have optional dependencies. ever.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;I am noting this so that it will not missed by the general public that &lt;b&gt;optional dependencies are going out of fashion&lt;/b&gt;.  &lt;br /&gt;&lt;br /&gt;The problem here is that if an optional dependency enables some useful feature (and otherwise why would you add it?) - then you should expect that someone writes a library using this feature and uploads that library to CPAN.  What that other guy should add to his dependencies?  How is he supposed to know which of your optional prerequisites are needed for his module?  And what if this is not about just two modules in dependency relation but rather a whole chain of them? Then it becomes a mess.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-5571112833858026197?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/5571112833858026197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=5571112833858026197' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/5571112833858026197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/5571112833858026197'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/09/optional-dependencies-go-out-of-fashion.html' title='Optional Dependencies Are Going Out of Fashion'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-1415552674406435420</id><published>2009-09-14T10:27:00.000-07:00</published><updated>2009-09-14T10:42:09.047-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>How they do it in Python (core libraries).</title><content type='html'>I don't read much from the Python blogosphere - so maybe it is not representative at all - but it seems that  &lt;a href="http://www.python.org/about/"&gt;Python 'batteries included'&lt;/a&gt; approach to core libraries is also &lt;a href="http://sayspy.blogspot.com/2009/09/evolving-standard-library.html"&gt;approaching its limits&lt;/a&gt;.  I am sure that debate will happen in any popular Open Source language after reaching some maturity level.  It is interesting what kind of compromise is proposed by the author of that piece:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;I would first prune the standard library down to a more core focus of libraries that require cross-platform expertise, using widely accepted standards, and stuff needed to simply get a script to run. In terms of cross-platform stuff, that would mean os, multiprocess, etc. These are modules that a typical developer would have a hell of a time getting working on all the OSs that CPython runs on.&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-1415552674406435420?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/1415552674406435420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=1415552674406435420' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1415552674406435420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1415552674406435420'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/09/how-they-do-it-in-python-core-libraries.html' title='How they do it in Python (core libraries).'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6837603720995398746</id><published>2009-09-12T06:20:00.000-07:00</published><updated>2009-09-12T09:03:07.945-07:00</updated><title type='text'>How to install Catalyst::Authentication::Credential::OpenID</title><content type='html'>This post is meant to be both a quick instruction and another data point for the CPAN installation problems thread of my blog posts.&lt;br /&gt;&lt;br /&gt;For those impatient the winning sequence of commands (for Debian/Ubuntu) is:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo apt-get install libgmp3-dev&lt;br /&gt;cpanp -i Math::BigInt::GMP&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;and now you can:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cpanp -i --force Catalyst::Authentication::Credential::OpenID&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now the story - at my pristine installation of Perl 5.10.1 on my Ubuntu box I discovered two problems with C:A:C:O installation.  First was a trivial POD error, detected with the new pod tests - this is why you need to do that &lt;code&gt;--force&lt;/code&gt; (it is fixed in the dev version).  The second is more interesting - installing one of the prerequisites - Crypt::DH seemed to take forever.  Fortunately by chance I found a good explanation of the problem in &lt;a href="http://search.cpan.org/~dmaki/Crypt-DH-GMP-0.00005/lib/Crypt/DH/GMP.pm#DESCRIPTION"&gt;Crypt::DH::GMP docs&lt;/a&gt; - apparently for any reasonable performance Crypt::DH needs Math::BigInt::GMP which is not in the prerequisites.  Without it it still works - but it can take serveral hours to pass the tests (&lt;a href="http://rt.cpan.org/Public/Bug/Display.html?id=19717"&gt;reported first 3 years ago&lt;/a&gt;).  So next thing is install Math::BigInt::GMP - unfortunately this is not automatic either - &lt;a href="http://rt.cpan.org/Public/Bug/Display.html?id=36202"&gt;you need to install gmp.h header file first&lt;/a&gt; (on Debian/Ubuntu it is the libgmp3-dev package).  This is why you need to execute the first two commands.&lt;br /&gt;&lt;br /&gt;I hope that will help someone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6837603720995398746?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6837603720995398746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6837603720995398746' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6837603720995398746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6837603720995398746'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/09/how-to-install-catalystauthenticationcr.html' title='How to install Catalyst::Authentication::Credential::OpenID'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-256033820149889010</id><published>2009-09-07T01:52:00.000-07:00</published><updated>2009-09-07T13:31:06.488-07:00</updated><title type='text'>Change Management and FOSS authors obligations</title><content type='html'>The two recent &lt;a href="http://labs.kraih.com/blog/2009/08/version-numbers-and-backwards-compatibility.html"&gt;controversies&lt;/a&gt; making &lt;a href="http://use.perl.org/~Alias/journal/39573"&gt;rounds in the Perl blogging community&lt;/a&gt; made me thinking about what obligations FOSS authors have to those using their code.  The traditional answer is none, but on the other hand there are some customs to the contrary - like maintaining API compatibility to at least one version back.  Some people have expectation that software not marked upfront as 'experimental' will follow that custom.  This is a good custom, because complete freedom for the authors can mean too much chaos for those using their code, but it is both not general enough and too radical in rejecting the traditional no obligations rule.  It is not enough - because not all API changes can be made with a backcompat layer, and as shows the example of &lt;a href="http://perlhacks.com/2009/09/moose-or-no-moose.php"&gt;Dave porting Array::Compare to Moose&lt;/a&gt; - there are also non API changes that can make downstream software unusable.  And it is too radical because of being an implicit, 'by default' rule.  And it is also too ambiguous in it's formulation because it does not state when the new releases can be published.  What we need is more general and explicite policies.&lt;br /&gt;&lt;br /&gt;Unexpectedly changing a library's API can be like pulling a rug from under the feet of authors of software using that library. In the past that was a rare event - and usually there was time to warn all the parties involved and let them fork the project if needed. Now in CPAN we have such huge dependency tries that even if it is still rare for the individual leaf nodes - it becomes quite frequent for the root nodes where all the changes cascade from the leaves. These deep dependency hierarchies also makes forking a lot more problematic as it can mean forking not just one library - but a whole path of them leading from the leaf up to the root.  CPAN might be still rather unique in it's size among distributed library projects - but with the overall &lt;a href="http://dirkriehle.com/publications/2008/the-total-growth-of-open-source/"&gt;exponential growth of FOSS software&lt;/a&gt; we can expect that to happen in other projects soon.  That's why if we want to continue the process of lego-like assembling software components out of more basic libraries we need those libraries to adhere to some change management policies.&lt;br /&gt;&lt;br /&gt;I am inviting FOSS authors to formulate their change management policies (and in particular &lt;a href="http://perlalchemy.blogspot.com/2009/08/lets-write-some-deprecation-policies.html"&gt;API deprecation policies&lt;/a&gt;) and voluntarily add them to the manuals.  I want to stress it - it is not about a top down rule forcing authors to do something - this is an invitation to voluntarily give up a bit of the authors freedom in leading the project in order to make it more useful.  The bulk of FOSS can still be published as a gift to the humanity with no strings attached.  I just want to show that additional option and also create some pre-canned policies that could be cut and pasted into the documentation just like the FOSS licences are.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-256033820149889010?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/256033820149889010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=256033820149889010' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/256033820149889010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/256033820149889010'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/09/change-management-and-foss-authors.html' title='Change Management and FOSS authors obligations'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6948594486720789045</id><published>2009-09-02T10:49:00.000-07:00</published><updated>2009-09-04T01:53:50.727-07:00</updated><title type='text'>What really fails in installation?</title><content type='html'>I've finally installed Perl 5.10.1 and I had to reinstall most of the modules I use.  I set &lt;code&gt;PERL_MM_USE_DEFAULT=1&lt;/code&gt; and did &lt;code&gt;make&lt;/code&gt; for a module that requires half of the modules on my computer.  Everything was installed automatically - with no additional intervention from me.  The morale of this is that if you are using Ubuntu and if you have installed all the external prerequisites - then the installation is really rather automatic.  The problem with systems other than a special flavour of Linux is both hard to solve and rather unsophisticated - we just need more people working on those systems and reporting and solving bugs.  Or at least that is the solution I can imagine.  But the problem with external prerequisites is where we could do better with just a bit of programming.&lt;br /&gt;&lt;br /&gt;I remove memcached from my system and try &lt;br /&gt;&lt;code&gt;&lt;br /&gt;zby@zby:~/progs/Enzyme$ cpanp i Cache::Memcached::Managed&lt;br /&gt;Installing Cache::Memcached::Managed (0.20)&lt;br /&gt;Running [/home/zby/local/bin/perl /usr/local/bin/cpanp-run-perl /home/zby/.cpanplus/5.10.1/build/Cache-Memcached-Managed-0.20/Makefile.PL]...&lt;br /&gt;No executable memcached found: No such file or directory&lt;br /&gt;Running [/usr/bin/make test]...&lt;br /&gt;PERL_DL_NONLAZY=1 /home/zby/local/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t&lt;br /&gt;Can't exec "memcached": No such file or directory at /home/zby/.cpanplus/5.10.1/build/Cache-Memcached-Managed-0.20/blib/lib/Cache/Memcached/Managed.pm line 843.&lt;br /&gt;#&lt;br /&gt;# Stopped memcached server&lt;br /&gt;# Looks like you planned 176 tests but ran 184.&lt;br /&gt;t/001basic.t .....&lt;br /&gt;Dubious, test returned 255 (wstat 65280, 0xff00)&lt;br /&gt;All 176 subtests passed&lt;br /&gt;        (less 177 skipped subtests: -1 okay)&lt;br /&gt;t/002inactive.t .. ok&lt;br /&gt;t/003multi.t ..... ok&lt;br /&gt;Can't exec "memcached": No such file or directory at /home/zby/.cpanplus/5.10.1/build/Cache-Memcached-Managed-0.20/blib/lib/Cache/Memcached/Managed.pm line 843.&lt;br /&gt;#&lt;br /&gt;# Stopped memcached server&lt;br /&gt;t/010fork.t ...... ok&lt;br /&gt;Can't exec "memcached": No such file or directory at /home/zby/.cpanplus/5.10.1/build/Cache-Memcached-Managed-0.20/blib/lib/Cache/Memcached/Managed.pm line 843.&lt;br /&gt;#&lt;br /&gt;# Stopped memcached server(s)&lt;br /&gt;t/020grab.t ...... ok&lt;br /&gt; &lt;br /&gt;Test Summary Report&lt;br /&gt;-------------------&lt;br /&gt;t/001basic.t (Wstat: 65280 Tests: 184 Failed: 8)&lt;br /&gt;  Failed tests: 177-184&lt;br /&gt;  Non-zero exit status: 255&lt;br /&gt;  Parse errors: Bad plan. You planned 176 tests but ran 184.&lt;br /&gt;Files=5, Tests=36330, 18 wallclock secs ( 6.12 usr 0.03 sys + 3.86 cusr 0.20 csys = 10.21 CPU)&lt;br /&gt;Result: FAIL&lt;br /&gt;Failed 1/5 test programs. 8/36330 subtests failed.&lt;br /&gt;make: *** [test_dynamic] Error 255&lt;br /&gt;[ERROR] MAKE TEST failed: Bad file descriptor PERL_DL_NONLAZY=1 /home/zby/local/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t&lt;br /&gt;Can't exec "memcached": No such file or directory at /home/zby/.cpanplus/5.10.1/build/Cache-Memcached-Managed-0.20/blib/lib/Cache/Memcached/Managed.pm line 843.&lt;br /&gt;#&lt;br /&gt;# Stopped memcached server&lt;br /&gt;# Looks like you planned 176 tests but ran 184.&lt;br /&gt;t/001basic.t .....&lt;br /&gt;Dubious, test returned 255 (wstat 65280, 0xff00)&lt;br /&gt;All 176 subtests passed&lt;br /&gt;        (less 177 skipped subtests: -1 okay)&lt;br /&gt;t/002inactive.t .. ok&lt;br /&gt;t/003multi.t ..... ok&lt;br /&gt;Can't exec "memcached": No such file or directory at /home/zby/.cpanplus/5.10.1/build/Cache-Memcached-Managed-0.20/blib/lib/Cache/Memcached/Managed.pm line 843.&lt;br /&gt;#&lt;br /&gt;# Stopped memcached server&lt;br /&gt;t/010fork.t ...... ok&lt;br /&gt;Can't exec "memcached": No such file or directory at /home/zby/.cpanplus/5.10.1/build/Cache-Memcached-Managed-0.20/blib/lib/Cache/Memcached/Managed.pm line 843.&lt;br /&gt;#&lt;br /&gt;# Stopped memcached server(s)&lt;br /&gt;t/020grab.t ...... ok&lt;br /&gt; &lt;br /&gt;Test Summary Report&lt;br /&gt;-------------------&lt;br /&gt;t/001basic.t (Wstat: 65280 Tests: 184 Failed: 8)&lt;br /&gt;  Failed tests: 177-184&lt;br /&gt;  Non-zero exit status: 255&lt;br /&gt;  Parse errors: Bad plan. You planned 176 tests but ran 184.&lt;br /&gt;Files=5, Tests=36330, 18 wallclock secs ( 6.12 usr 0.03 sys + 3.86 cusr 0.20 csys = 10.21 CPU)&lt;br /&gt;Result: FAIL&lt;br /&gt;Failed 1/5 test programs. 8/36330 subtests failed.&lt;br /&gt;make: *** [test_dynamic] Error 255&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;The tests for 'Cache::Memcached::Managed' failed. Would you like me to proceed anyway or should we abort?&lt;br /&gt; &lt;br /&gt;Proceed anyway? [y/N]:&lt;br /&gt;[ERROR] Unable to create a new distribution object for 'Cache::Memcached::Managed' -- cannot continue&lt;br /&gt; &lt;br /&gt;*** Install log written to:&lt;br /&gt;  /home/zby/.cpanplus/install-logs/Cache-Memcached-Managed-0.20-1251915361.log&lt;br /&gt; &lt;br /&gt;Error installing 'Cache::Memcached::Managed'&lt;br /&gt;Problem installing one or more modules&lt;br /&gt; &lt;br /&gt;zby@zby:~/progs/Enzyme$&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Yeah - the information is there - but now imagine that this was a deep dependency tree with lot's of similar external prerequisites.  You try to install the module - it fails, you view the log, locate the problem, install the external dependency, run the installation again and it fails again.  Everytime you need to parse the really long installation log and try to understand what happened.  It is not that complicated (although it can become complicated when there aren't so explicite error messages, or when there are other installation failures mixed together) - but it is intimidating and really time consuming.  Definitively it is not something that a newcomer would be able to do.  But external dependencies are not something extraordinary - they are rather standard, this procedure I described here is not exactly a failure mode - it is anticipated.&lt;br /&gt;&lt;br /&gt;Someone could argue that when I install &lt;code&gt;Cache::Memcached::Managed&lt;/code&gt; I should know that it needs the &lt;code&gt;memcached&lt;/code&gt; binary - but it is only obvious for those that know that module, and if that module is somewhere deep in the dependency tree you might not even realize that you are installing it.&lt;br /&gt;&lt;br /&gt;Now imagine this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;zby@zby:~/progs/Enzyme$ cpanp i Some::Module&lt;br /&gt;Computing prerequisites.&lt;br /&gt;You have unmet external prerequisites:&lt;br /&gt;memcached&lt;br /&gt;xslt version 1.1.18&lt;br /&gt;...&lt;br /&gt;Please install the prerequisites first then run the installation again.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;wouldn't that be helpful?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;PS.&lt;/b&gt; How about&lt;br /&gt;&lt;code&gt;&lt;br /&gt;requires_external memcached =&gt; sub { -x "memcached" }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;in Makefile.PL?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6948594486720789045?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6948594486720789045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6948594486720789045' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6948594486720789045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6948594486720789045'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/09/what-really-fails-in-installation.html' title='What really fails in installation?'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-1256801383312861669</id><published>2009-08-30T07:53:00.001-07:00</published><updated>2009-08-31T02:19:46.031-07:00</updated><title type='text'>CPAN installation failures</title><content type='html'>The "Chance of all tests passing" at the &lt;a href="http://deps.cpantesters.org/?module=Catalyst::Runtime;perl=latest"&gt;CPAN dependencies and test results checker&lt;/a&gt; is not a &lt;a href="http://deps.cpantesters.org/static/overall-chance.html"&gt;scientific measure&lt;/a&gt; - but it is great in making it visible that installing from CPAN is still a game of chance with quite big odds of failure.  The linked above Catalyst dependencies page quotes the 'probability' of installation failure as 22%, and that is for the most advertised Perl web framework.  The important thing in that picture is how this relatively big failure chance comes from the individual small failure chances of the Catalyst prerequisites.&lt;br /&gt;&lt;br /&gt;So what can we do?  One thing that I would propose is to &lt;a href="http://www.mail-archive.com/module-authors@perl.org/msg07485.html"&gt;stop using optional features and dependencies&lt;/a&gt; because they really get into the way of automatic installs.  We can also &lt;a href="http://use.perl.org/~Alias/journal/39456"&gt; simplify the dependency graph of some more important modules&lt;/a&gt;, make better statistics about the failure rates and they origins, but probably the most effective way will be to be just &lt;a href="http://jjnapiorkowski.vox.com/library/post/trouble-installing-with-cpan.html"&gt;more vigilant about the test failures in our modules and in the prerequisites&lt;/a&gt;.  The important lesson here is that a 1% failure rate seems like nothing important - but it can make our module inadequate to become a prerequisite for some more complex library.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-1256801383312861669?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/1256801383312861669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=1256801383312861669' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1256801383312861669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1256801383312861669'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/08/cpan-installation-failures.html' title='CPAN installation failures'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-1686811730515806078</id><published>2009-08-23T12:39:00.000-07:00</published><updated>2009-08-24T11:34:30.993-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Let's write some deprecation policies</title><content type='html'>Sebastian writes &lt;a href="http://labs.kraih.com/blog/2009/08/version-numbers-and-backwards-compatibility.html"&gt; about version numbers and backwards compatibility&lt;/a&gt; and asks:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Should a project have deprecation policies as soon as it hits CPAN with a development release?&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;I think the answer should be yes - there should always be a deprecation policy.  But this deprecation policy does not need to be the full monty of always keeping the backcompat to at least one major version, using strict deprecation cycles etc - it just needs to be stated explicitely and not relying on the version numbering convention as they are not really universal.  There is no negative side to putting a few sentences into the docs, only a bit work to formulate them.  And here is my idea:&lt;br /&gt;&lt;br /&gt;Let's write some deprecation policies&lt;br /&gt;&lt;br /&gt;Let's have a list of well formulated policies covering as much as we can of possible circumstances (from experimental to mature, and from one-person projects to team work) that could be copied to the CPAN distribution docs with minimal effort.  For the start - here are some ideas:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Experimental - no policies at all, use at your own risk&lt;br /&gt;&lt;li&gt;Experimental with mailing list announcements of new versions and promise to take into account problems encountered by people testing the new code&lt;br /&gt;&lt;li&gt;Backcompat to one version, with a specific minimal time between versions&lt;br /&gt;&lt;li&gt;Backcompat to one major version, with a specific minimal time between major releases&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt;&lt;br /&gt;In related news &lt;a href="http://www.shadowcat.co.uk/blog/matt-s-trout/backwards-compatibility-and-migration-paths/"&gt;mst gives an overview of techniques that can be used for maintaining back-compat&lt;/a&gt; - sometimes these are really simple things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-1686811730515806078?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/1686811730515806078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=1686811730515806078' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1686811730515806078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1686811730515806078'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/08/lets-write-some-deprecation-policies.html' title='Let&apos;s write some deprecation policies'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3733394070113933396</id><published>2009-08-14T01:07:00.000-07:00</published><updated>2009-08-14T05:21:12.466-07:00</updated><title type='text'>Dissecting the Rails Screencast</title><content type='html'>Most comments to my &lt;a href="http://perlalchemy.blogspot.com/2009/08/marketing-for-perlers.html"&gt;previous post on marketing for the Perl community&lt;/a&gt; focused on the visual identity of Perl web sites. It is very important, but marketing is not only that.  Ruby on Rails would not be what it is now if not for the &lt;a href="http://media.rubyonrails.org/video/rails-0-5.mov"&gt;RoR screencast&lt;/a&gt;.  It was:&lt;br /&gt;&lt;dl&gt;&lt;br /&gt;&lt;dt&gt;Simple&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;Writing a blog engine - what can be simpler?&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;Unexpected&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;&lt;br /&gt;The first surprise is the medium - that was the one of the first popular screencasts to circulate the Internet.  But of course the main load of unexpectedness was in the fact that a simplistic, but still functional, blog engine can be build in 15 minutes.  Not months or years of a team of programmers, a designer and a HTML coder - but 15 minutes of one person - that is surprising.&lt;br /&gt;&lt;/dd&gt;&lt;br /&gt;&lt;br /&gt;&lt;dt&gt;Concrete&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;&lt;br /&gt;That was not an abstract plan, framework with holes to be filled in later - but a concrete implementation.  And once again - blog engine - what can be more concrete for the web afficionados?&lt;br /&gt;&lt;/dd&gt;&lt;br /&gt;&lt;br /&gt;&lt;dt&gt;Credible&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;&lt;br /&gt;You can see it for yourself - it is not a description of how to do it - it is filmed the whole process of doing it.  And later you can also try it on your own.&lt;br /&gt;&lt;/dd&gt;&lt;br /&gt;&lt;br /&gt;&lt;dt&gt;Emotional&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;&lt;br /&gt;Not really - but you don't need to cover all of the points.&lt;br /&gt;&lt;/dd&gt;&lt;br /&gt;&lt;br /&gt;&lt;dt&gt;Story&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;&lt;br /&gt;This is the most important thing - the screencast is a story.  The viewer can easily imagine himself writing his own web application with the same efficiency - this is how stories work.&lt;br /&gt;&lt;/dd&gt;&lt;br /&gt;&lt;/dl&gt;&lt;br /&gt;&lt;br /&gt;PS. Don't read this as an argument for (more) screencasts. Yes - they can be effective - but it all depends.  What I am advocating here is using that checklist for all marketing projects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3733394070113933396?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3733394070113933396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3733394070113933396' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3733394070113933396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3733394070113933396'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/08/dissecting-rails-screencast.html' title='Dissecting the Rails Screencast'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-1046992400638872103</id><published>2009-08-11T04:56:00.000-07:00</published><updated>2009-08-11T06:00:15.992-07:00</updated><title type='text'>Marketing for Perlers</title><content type='html'>Sources on the intertubes &lt;a href="http://use.perl.org/~Ovid/journal/39409"&gt;report&lt;/a&gt; that marketing &lt;a href="http://szabgab.com/blog/2009/08/1249933214.html"&gt;is becoming&lt;/a&gt; a hot topic around the Perl community.  It might be a good time to learn a bit about that subject and perhaps exchange some recommendations.  I don't want to retract anyone from hiring a professional marketer, to the contrary I think this is the mature thing to do. We need to admit that our own knowledge in that area is limited and seek professional help.  But learning a bit more will not hurt.  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The book that I would like to recommend is &lt;a href="http://madetostick.com/"&gt;Made to Stick. Why Some Ideas Survive and Others Die ...&lt;/a&gt; - it is about creating messages that will be remembered.  It is build around a simple list: &lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Simple&lt;br /&gt;&lt;li&gt;Unexpected&lt;br /&gt;&lt;li&gt;Concrete&lt;br /&gt;&lt;li&gt;Credible&lt;br /&gt;&lt;li&gt;Emotional&lt;br /&gt;&lt;li&gt;Stories&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;these are the ingredients of an effective marketing message (and yeah the first letters do form an mnemotechnic acronym).  &lt;br /&gt;&lt;br /&gt;The message needs to be &lt;b&gt;simple&lt;/b&gt;, so that the basics are easily understood and can be easily spread around.  I think this will be well understood to programmers.  It is not about dumbing it down - it is about finding the real core.  It needs to be &lt;b&gt;unexpected&lt;/b&gt; to catch peoples attention. To hold attention the book advices to use &lt;em&gt;curiosity gaps&lt;/em&gt;.  Next quality is &lt;b&gt;concrete&lt;/b&gt; - this is about involving things the audience already knows well, tangible things and painting a mental image.  &lt;b&gt;Credibility&lt;/b&gt; comes from inside or from an outside authority, inside credibility comes from using vivid details, statistics but also can be gained by inviting the audience to test for themselves.  &lt;b&gt;Emotional&lt;/b&gt; is about speaking to emotions.  Finally the best messages are &lt;b&gt;stories&lt;/b&gt; - the power of story telling comes from the fact that that people reach the conclusions for themselves and they easily absorb them as their own.&lt;br /&gt;&lt;br /&gt;Apparently this was tested by the ads business:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;The final group was trained for two hours on how to use the six creative templates. Once again, the fifteen best ads were selected by the creative director and tested with consumers. Suddenly these novices sprouted creativity. Their ads were rated as 50 percent more creative and produced a 55 percent more positive attitude toward the products advertised. This is a stunning improvement for a two-hour investment in learning a few basic templates! It appears that there are indeed systematic ways to produce creative ideas.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;from &lt;a href="http://www.madetostick.com/excerpts/"&gt;excerpts&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-1046992400638872103?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/1046992400638872103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=1046992400638872103' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1046992400638872103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1046992400638872103'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/08/marketing-for-perlers.html' title='Marketing for Perlers'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3106654859725567747</id><published>2009-08-07T00:08:00.000-07:00</published><updated>2009-08-07T04:28:57.316-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>The Catalyst API</title><content type='html'>Now, after the Moose port is completed, it looks like a good time for reviewing the Catalyst API. It's not a secret that in my opinion some of the Catalyst practice is a cargo cult (&lt;a href=" http://perlalchemy.blogspot.com/2009/07/is-using-catalyst-forward-method-cargo.html"&gt;for example using forward instead of a subroutine call&lt;/a&gt;), &lt;a href="http://perlalchemy.blogspot.com/2007/04/matchparams-for-auto-actions.html"&gt;other parts could be greatly simplified&lt;/a&gt;.  In &lt;a href="http://blog.urth.org/2009/08/how-i-use-catalyst.html"&gt;How I Use Catalyst&lt;/a&gt; the interesting part is how Dave also does not use some important parts of the Catalyst API, and Marcus in his reply, even though he disagrees with Dave, still he does agree that there might be a &lt;a href="http://marcus.nordaaker.com/2009/08/model-adaptors-for-catalyst/"&gt;more suitable API&lt;/a&gt; for some things.&lt;br /&gt;&lt;br /&gt;It's time to review the API, check how Moose can improve it, remove the redundancies and make it slim.&lt;br /&gt;&lt;br /&gt;One more piece of food for thought: the thing that always bothered me is the first parameter every action receives:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/163779.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;I've never seen it used.  I even was never sure if that thing is a controller object or if it is the controller class (i.e. if the actions are class or object methods), is it ever explained in the docs?  Now I tested it and the output was:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/163783.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;so at least that action was an object method.  I've reviewed the whole &lt;a href="http://search.cpan.org/~hkclark/Catalyst-Manual-5.8000/lib/Catalyst/Manual/Tutorial.pod"&gt;Catalyst Tutorial&lt;/a&gt; and, even though this parameter is passed to every action example there it is used in only a couple places (as &lt;code&gt;$self-&gt;action_for('list')&lt;/code&gt; and &lt;code&gt;$self-&gt;roles&lt;/code&gt;).  This does not seem like the best Huffman coding.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3106654859725567747?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3106654859725567747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3106654859725567747' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3106654859725567747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3106654859725567747'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/08/catalyst-api.html' title='The Catalyst API'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6870257601726819526</id><published>2009-08-02T23:33:00.000-07:00</published><updated>2009-08-03T01:16:43.756-07:00</updated><title type='text'>Dear TPF - don't send money, send thank you letters</title><content type='html'>I have already commented at the &lt;a href="http://news.perlfoundation.org/2009/07/proposed_payments_for_clearing.html"&gt;Proposed Payments for Clearing Perl 5 Bugs&lt;/a&gt; blog post from The Perl Foundation - but now I think I have an even better idea.  I am now unemployed, maybe I could try this bug hunting as a way to get some income during these hard times, but the money, that is most probably at stake, could hardly solve any problem for me.  Still there is one thing that could have much impact on my situation - I am sure you already know what I have on mind - a printed thank you letter from The Perl Foundation that I could take with me to the interviews.  This would not cost much, even for something printed on a nice paper - but it could have a great impact on peoples careers.&lt;br /&gt;&lt;br /&gt;Even if the money rewards are already something decided - and no change can be made - TPF could at least accompany them with such a thank you letter.  And there should be a way to make it signed by Larry Wall himself - this is crucial for the impressiveness factor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6870257601726819526?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6870257601726819526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6870257601726819526' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6870257601726819526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6870257601726819526'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/08/tpf-dont-send-money-send-thank-you.html' title='Dear TPF - don&apos;t send money, send thank you letters'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3065308399907877544</id><published>2009-07-31T01:04:00.000-07:00</published><updated>2009-08-02T01:21:34.032-07:00</updated><title type='text'>Fixing dependencies</title><content type='html'>Fixing other people code is not easy - but this is what we need to do if we want to clean our dependencies.  In answer to John's &lt;a href="http://jjnapiorkowski.vox.com/library/post/trouble-installing-with-cpan.html"&gt;invitation&lt;/a&gt; here is what I did.&lt;br /&gt;&lt;br /&gt;I wanted to write some code using Catalyst::Authentication::Credential::OpenID unfortunately one of it's dependencies &lt;a href="http://matrix.cpantesters.org/?dist=LWPx-ParanoidAgent+1.06"&gt;fails it's tests&lt;/a&gt;.  Here I'll document how I analysed that and produced a patch, it's not yet approved by the author - but the tests pass.&lt;br /&gt;&lt;br /&gt;Step first - checkout the ParanoidAged from it's repository (I had the repository address from an &lt;a href="http://lists.scsys.co.uk/pipermail/catalyst/2009-July/023150.html"&gt;email to the Catalyst mailing list&lt;/a&gt;). If you don't have access to the repository of your failing dependency - then just download the source from CPAN unpack it and work from there.  Then run the tests:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;zby@zby:~/progs/pa$ perl -Ilib t/00-all.t&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;ok 27&lt;br /&gt;5 second tarpit (tolerance 2)...&lt;br /&gt;not ok 28&lt;br /&gt;#   Failed test at t/00-all.t line 180.&lt;br /&gt;3 second tarpit (tolerance 4)...&lt;br /&gt;ok 29&lt;br /&gt;Killing child pid: 7669&lt;br /&gt;# Looks like you failed 1 test of 29.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;OK - the failing test is at line 180.  Let's see what is there:&lt;br /&gt;&lt;script src="http://gist.github.com/159989.js"&gt;&lt;/script&gt;&lt;br /&gt;I changed that to:&lt;br /&gt;&lt;script src="http://gist.github.com/159990.js"&gt;&lt;/script&gt;&lt;br /&gt;ran the tests and save my debug output:&lt;br /&gt;&lt;code&gt;zby@zby:~/progs/pa$ perl t/00-all.t 2&gt;debug&lt;/code&gt;.  &lt;br /&gt;What I got there is:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/159991.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Now the info is there - but of course I did not spot it at once.  I did a lot of more debugging and testing other hypothesis before I focused on: &lt;code&gt;'x-died' =&gt; 'read timeout at lib/LWPx/Protocol/http_paranoid.pm line 394.'&lt;/code&gt;.  Yeah interesting - something died, but no error was reported.  The line in question is:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/159993.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;To get some more evidence I changed that to:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/159994.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Now the debug output changes to:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/159995.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;And again - it is there - but to spot it I had to play with the debugger first.  I don't remember what exactly I did - but finally I sow it - there are two evals in this stack trace, the first one is in LWP::Protocol and the second in lib/LWPx/ParanoidAgent.pm line 313.  I checked that second eval - and yeah - it tried to retrieve the error already catched by the first one.  So when there was a timeout the agent was aborting the retrieval - but the error was being cleared and not reported.  I wrote following patch:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/159997.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;and now all the tests pass. Finally I &lt;a href="https://rt.cpan.org/Ticket/Display.html?id=48345"&gt;uploaded the patch to RT&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3065308399907877544?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3065308399907877544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3065308399907877544' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3065308399907877544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3065308399907877544'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/07/fixing-dependencies.html' title='Fixing dependencies'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-268184347256205005</id><published>2009-07-29T05:22:00.000-07:00</published><updated>2009-07-29T11:24:37.735-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>On dependencies</title><content type='html'>Ovid &lt;a href="http://use.perl.org/~Ovid/journal/39368?from=rss"&gt;writes about Mojolicious::Lite&lt;/a&gt;: &lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;The fact that it has no dependencies makes it even more compelling.It's the sort of thing one could more easily attract new developers with. Can you imagine rewriting my old CGI course with something like this? Or maybe a way to introduce new users to Perl? There are many excellent Perl frameworks out there which I would, nonetheless, hesitate to start new users on. Just trying to set up CPAN can be difficult for them; working through even one test failure is often too much. For people who want to jump in and learn "Web programming", though, this might work.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;On the other hand Jay advices to stop worrying about dependencies &lt;a href="http://www.catalyzed.org/2009/07/the-lie-of-independence.html"&gt;The lie of independence - or - how I learned to stop worrying and love the dependency chain&lt;/a&gt;.  There is truth in both statements.  I have the impression that the problem of CPAN dependencies have improved much recently.  The visibility of installation problems directly from the cpan search engine (&lt;a href="http://matrix.cpantesters.org/"&gt;cpan testers matrix&lt;/a&gt;, &lt;a href="http://deps.cpantesters.org/"&gt;dependencies review&lt;/a&gt;) is a great step ahead.  But still installing Catalyst and DBIC and TT is a big hurdle - and I can understand why Ovid is not enthusiastic about teaching Perl novices how to do that.&lt;br /&gt;&lt;br /&gt;For me Mojo sounds like iPod - slick and beautiful and really useful - but you are not supposed to change the battery.  It is a nicely integrated product - but somehow closed.  The author apparently tries to make it perfect, tries to polish every detail - what perhaps would not be possible if he had to compromise with the visions of the authors of the other packages. I can feel his frustration here.  But rejecting all dependencies and rewriting everything in his own way sounds a bit extreme and not welcoming.&lt;br /&gt;&lt;br /&gt;The big question here is how much can we trust fellow CPAN authors to make the right decisions, can we rely on their work?  Can someone, who put's a lot of attention for the details of his API, rely on modules with imperfect APIs, perhaps spoiling his own work and not become insane?  The &lt;a href="http://use.perl.org/comments.pl?sid=43461"&gt;story of the phalanx project&lt;/a&gt; shows that there are no easy answers to these questions, but I believe we can do better than rewriting everything from scratch each time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-268184347256205005?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/268184347256205005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=268184347256205005' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/268184347256205005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/268184347256205005'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/07/on-dependencies.html' title='On dependencies'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3307083921297989605</id><published>2009-07-26T03:59:00.000-07:00</published><updated>2009-07-26T04:35:07.699-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Google Wave</title><content type='html'>One, sometimes feverishly defended, rule of our technical irc channels is about not pasting code into the conversation.  To show your code you are supposed to use some web based paste application and then copy the link into the channel. The need to use two separate tools, irc client and web browser, for one task, code review, is just a small annoyance - but eliminating those small annoyances is the only way towards really usable software.  Many people have internalized the procedure so much, that they don't think about it any more and I am sure there will be some of them arguing that this is not annoying at all.  But there are additional steps to do: choose the tool, paste the link, switch the windows and all this is a burden to the brain, even if it is processed in the background - it still consumes some brain resources.&lt;br /&gt;&lt;br /&gt;And now imagine that you have it in one tool - not only those additional steps go away - but it also opens the way for new features like seeing a pointer to the part of the code that the other person is talking about, seeing his edits in real-time and commenting on them immediately etc.&lt;br /&gt;&lt;br /&gt;This is why I believe in convergence of communication tools.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3307083921297989605?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3307083921297989605/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3307083921297989605' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3307083921297989605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3307083921297989605'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/07/google-wave.html' title='Google Wave'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3381176969859514676</id><published>2009-07-17T23:44:00.000-07:00</published><updated>2009-07-19T02:23:01.861-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>Nothing is forever</title><content type='html'>I have been writing about the scaffolding metaphor - but after some conversations with my colleagues I realized that I did not do a good job there.  I did not conduct well the main idea: nothing is forever. No library and no program is forever and we should not shy off from writing libraries that are useful only at some phase of the application construction.  It is still valuable if you can quickly get to the point of having a preview, a simplified prototype of the functionality you need even if eventually you'll remove all of that prototype code from the project.  This is very 'agile' and it is also 'worse is better (if you can have it early)' and those libraries, those tools that you use only temporarily, I call the scaffolding.&lt;br /&gt;&lt;br /&gt;Now one would ask why write a library that is useful only temporarily?  Why not include at once all the parts needed in the final product?  There can be several reasons:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;something that is only a part of the scaffolding in one project can stay in the final solution in another one&lt;br /&gt;&lt;li&gt;the author of the library might not yet fully understand the problem, and it can take years to reach the right abstraction&lt;br /&gt;&lt;li&gt;the distribution of possibly needed modification can be so uniform that there is no reason to concentrate on one of them more than on another one and it is virtually impossible to cover them all&lt;br /&gt;&lt;li&gt;and finally: nothing is forever - you never know where a project will go in the future and what you'll need to change&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;A good example (of the third point) are code samples from manuals - you copy them to quickly get something working - but later you modify it and sometimes you change every character from the original.  Another one can be the scaffolding code in Rails - you can debate if it fits the first or the second or other points - but it was useful to a lot of people.&lt;br /&gt;&lt;br /&gt;Every library can be used as scaffolding - so why not accept this and help the developers in using it that way?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3381176969859514676?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3381176969859514676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3381176969859514676' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3381176969859514676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3381176969859514676'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/07/nothing-is-forever.html' title='Nothing is forever'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-1288625872175002390</id><published>2009-07-13T14:23:00.000-07:00</published><updated>2009-07-13T15:03:30.076-07:00</updated><title type='text'>CPAN and code reuse</title><content type='html'>CPAN is wonderful thing - it is a great achievement of the whole Perl community and the thing that makes it apart from other languages.  But somehow it works mostly for libraries.  And what about the other modes of code reuse?  How about CPAN for code examples?  One can say we don't need CPAN for code examples - everyone is using code examples all the time and they do that without any special infrastructure.  But what I see around is that some of CPAN modules are actually code examples in disguise.  Some of them would be better without any code in the package and only documentation and tests validating the documented techniques.  Hmm maybe we don't really need a separate CPAN for that - maybe we can keep them at the existing one - and just mark them in a special way?  And maybe we need some social acceptance for packaging such 'empty' libraries?&lt;br /&gt;&lt;br /&gt;And what with applications?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-1288625872175002390?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/1288625872175002390/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=1288625872175002390' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1288625872175002390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/1288625872175002390'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/07/cpan-and-code-reuse.html' title='CPAN and code reuse'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-6443552620582335233</id><published>2009-07-09T00:57:00.000-07:00</published><updated>2009-07-09T01:18:44.520-07:00</updated><title type='text'>Code reuse styles</title><content type='html'>There is much buzz around PHP tools like Drupal and Joomla.  They are ready-made solutions, but in fact there is also a lot of tweaking the templates and writing add-ons.  It seems to work very well - the clients get something usable from the beginning - and later they can modify it to fit their purpose better.  This is very agile.  In contrast the reuse in Perl is mostly around libraries.  This is much more flexible - you don't tweak a ready solution - you assemble it from the thousands of CPAN packages.  But it is also less agile.  &lt;br /&gt;&lt;br /&gt;I wonder why it is like that.  There are some technical differences that lead developers in one or the other direction - but there is also a cultural/psychological cause.  Doing some self-analysis I must admit that I am not really enthusiastic about contributing to a Perl CMS (like for example Bricolage) - in my view all the already-build solutions use obsolete libraries.  I'd rather contribute to building the perfect library - then code an extension to Bricloage.  I have the feeling that I am not alone in that crazy perfectionism around Perl hackers.  PHP clearly wins here with more pragmatic approach.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-6443552620582335233?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/6443552620582335233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=6443552620582335233' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6443552620582335233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/6443552620582335233'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/07/code-reuse-styles.html' title='Code reuse styles'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-3583544533424512139</id><published>2009-07-06T10:56:00.000-07:00</published><updated>2009-07-06T11:04:49.239-07:00</updated><title type='text'>Deprecated code analyzer for HTML::FormHandler</title><content type='html'>So the other day I've read &lt;a href="http://blog.robin.smidsrod.no/index.php/2009/07/03/deprecated-code-analyzer-for-perl"&gt;Deprecated code analyzer for perl&lt;/a&gt; and I thought - this is a GREAT idea!  And I &lt;a href="http://github.com/gshank/html-formhandler/blob/b6b8f7f83797e8802acd782d0863e275861ac85b/lib/Perl/Critic/Policy/FormHandler/Deprecations.pm"&gt;stole it for HTML::FormHandler&lt;/a&gt;.  Now with new releases our users will have a tool to find all the deprecated API calls in their code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-3583544533424512139?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/3583544533424512139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=3583544533424512139' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3583544533424512139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/3583544533424512139'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/07/deprecated-code-analyzer-for.html' title='Deprecated code analyzer for HTML::FormHandler'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36345871.post-8578823852819628500</id><published>2009-07-04T03:01:00.000-07:00</published><updated>2009-07-04T04:01:11.002-07:00</updated><title type='text'>Is using the Catalyst 'forward' method a cargo cult?</title><content type='html'>I think most Catalyst new-commers believe that to execute a Catalyst action you need to forward to it - this is the effect of all the examples in the manual doing that instead of using the standard Perl syntax of calling a method on a class. Of course there are some differences between those two - but I am sure that for most cases the standard Perl way of doing it is perfectly enough.&lt;br /&gt;&lt;br /&gt;And when it is not enough?  What are really the differences between:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$c-&gt;forward( 'some_action' )&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;and the standard Perl:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$self-&gt;some_action( $c );&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;As far as I know the only two differences are that the first call is called in an eval and that it is logged in the debug output (if it is switched on), maybe there are some other minor differences, but, I am sure, nothing dramatical.  It can helpful/needed sometimes (and othertimes that eval can be a nuisance), but it is also easy to add.  Of course this is the simplest case - &lt;a href="http://search.cpan.org/~flora/Catalyst-Runtime/lib/Catalyst.pm#$c-%3Eforward(_$action_[,_\@arguments_]_)"&gt;'forward' signature&lt;/a&gt; is more complex and it does amazing things for finding the action "by it's private name" - but for most of the cases &lt;a href="http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It"&gt;you ain't gonna need it&lt;/a&gt; and you can use ye old Perl syntax to make the call and spare yourself learning how to pass parameters to the forward call.  &lt;br /&gt;&lt;br /&gt;Related reading: &lt;a href="http://www.reddit.com/r/programming/comments/8y0o6/premature_flexibilization_is_the_root_of_whatever/"&gt;Premature Flexibilization Is The Root of Whatever Evil Is Left&lt;/a&gt; - a reddit discussion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36345871-8578823852819628500?l=perlalchemy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://perlalchemy.blogspot.com/feeds/8578823852819628500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36345871&amp;postID=8578823852819628500' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8578823852819628500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36345871/posts/default/8578823852819628500'/><link rel='alternate' type='text/html' href='http://perlalchemy.blogspot.com/2009/07/is-using-catalyst-forward-method-cargo.html' title='Is using the Catalyst &apos;forward&apos; method a cargo cult?'/><author><name>zby</name><uri>http://www.blogger.com/profile/04636763782334128869</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_Is2XdgBuTTM/SoaNuNpeqiI/AAAAAAAAAA8/zfdBBjUzOi0/S220/zby2009_07_01.JPG'/></author><thr:total>4</thr:total></entry></feed>
