<?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-7103012096530045108</id><updated>2011-08-03T15:35:22.714-04:00</updated><category term='Perl'/><category term='perl formhandler programming'/><category term='FormHandler'/><category term='programming'/><category term='Moose'/><category term='Catalyst'/><title type='text'>catdev</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>19</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-444179292850913424</id><published>2010-03-08T18:20:00.002-05:00</published><updated>2010-03-08T18:42:07.487-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='FormHandler'/><title type='text'>HTML::FormHandler result object</title><content type='html'>&lt;p&gt;Sometime last year I re-structured HTML::FormHandler so that the input and values that are produced by the form validation process are stored in separate result objects. There is an alternate method 'run' (as opposed to the usual 'process' method) to get these objects, or you can get them from a form after 'process'.&lt;p&gt;
&lt;p&gt;I expected that those who were interested in using this would materialize and provide input into what additional facilities/hooks were needed, but as far as I can tell nobody has actually used the feature. I think that it's a fair assumption that nobody actually knows about it, or can't figure out the point.&lt;p&gt;
&lt;p&gt;The standard way to use FormHandler is (simplified) something like:&lt;/p&gt;
&lt;pre&gt;
    my $form = MyApp::Form-&gt;new;
    $form-&gt;process( params =&gt; $params, item =&gt; $item, ...);
    if( $form-&gt;validated ) {
     ....
    }
&lt;/pre&gt;
&lt;p&gt;When using the the result object, the form acts like a kind of factory, and it looks like this:&lt;/p&gt;
&lt;pre&gt;
    my $form = MyApp::Form-&gt;new;
    my $result = $form-&gt;run( params =&gt; $parsms, item =&gt; $item, ... );
    if( $result-&gt;validated ) {
       ...
    }
&lt;/pre&gt;
&lt;p&gt;...and all the state is stored in the result objects, ideally leaving none left in the form&lt;/p&gt;
&lt;p&gt;Currently result objects refer back to some attributes of the form object for rendering, since a number of rendering related definitions are stored there. It would be possible to decouple that, but then you'd end up having to define the validation and rendering aspects of the fields in two places.&lt;p&gt;
&lt;p&gt;In practice, the separation between static (form definition) information and ephemeral data is not nearly as clearcut as you might think. I find that people often want to change attributes that would probably be initially defined as static based on values that are passed in. It is possible to do this in a clean way, of course. But since the previous results are always cleared out at the beginning of each 'process' call, in practice the difference between using the form with 'process' and using it with 'run' aren't huge.&lt;/p&gt;
&lt;p&gt;Nonetheless, I am sure there are people who have good use cases for this alternative architecture, and would love to have people pound on it and use it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-444179292850913424?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/444179292850913424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=444179292850913424' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/444179292850913424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/444179292850913424'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2010/03/htmlformhandler-result-object.html' title='HTML::FormHandler result object'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-2794221169944718137</id><published>2010-02-21T20:38:00.003-05:00</published><updated>2010-02-22T21:31:09.287-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='FormHandler'/><title type='text'>creating a FormHandler form from a DBIx::Class result source</title><content type='html'>&lt;p&gt;Someone regularly pops up in #formhandler looking for a way to automatically create a form from a DBIx::Class result source. After explaining how to create a fairly simple role that would do that, the people have always gone away and nothing ever came of it.&lt;/p&gt;
&lt;p&gt;I have mixed feelings about the idea, myself. Sure, there's a theoretical benefit to not defining things in multiple places. But in practice, there's almost always differences in selection, presentation, etc, that mean that an automatically derived form is of surprisingly little use. At least in &lt;b&gt;my&lt;/b&gt; experience. YMMV. It's awfully easy to take the list of column names and type "has_field 'column';" &lt;/p&gt;
&lt;p&gt;But then the eleventeenth person asked about automatic form generation - and the yaks must have been particularly hairy this weekend...because I made a good start at shaving this particular one.&lt;/p&gt;
&lt;p&gt;There is now a new trait: HTML::FormHandler::TraitFor::DBICFields, and a package to do the mapping from source info to field definitions: HTML::FormHandler::Model::DBIC::TypeMap. I'm pretty sure that it's not quite right yet, but at least a start has been made, and it should be easier for those that want this kind of functionality to polish, add, and tweak. For one thing, it doesn't handle relationships yet. FormHandler can create form fields out of a lot of the standard DBIx::Class relationships, yet it is often &lt;i&gt;not&lt;/i&gt; what you would want to have happen automatically. So I think skipping relationships as a default is probably OK.&lt;/p&gt;
&lt;p&gt;Anyway, here is how to create a form by looking at the source columns:&lt;/p&gt;
&lt;pre&gt;
   my $book = $schema-&gt;resultset('Book')-&gt;find(1);
   my $form = HTML::FormHandler::Model::DBIC-&gt;new_with_traits( 
      traits =&gt; ['HTML::FormHandler::TraitFor::DBICFields'],
      field_list =&gt; [ 'submit' =&gt; 
          { type =&gt; 'Submit', value =&gt; 'Save', order =&gt; 99 } ],
      item =&gt; $book );
&lt;/pre&gt;
&lt;p&gt;The field_list attribute is because I thought it was better to explicitly specify the submit field, rather than automatically create it. I could be argued out of it...&lt;/p&gt;
&lt;p&gt;The interface is only a few hours old, so if you have thoughts about how this should work, this is the time to speak up, before somebody starts using it and it becomes harder to change. :-)&lt;/p&gt;
&lt;p&gt;Speaking of dynamic forms... HTML::FormHandler is known for it's Moose-y sugar interface, but there are other ways to create a FormHandler form. Using a 'field_list' as a parameter to 'new' works fine to create a dynamic form (though there are things that are possible inside a class that just can't be done with that kind of interface):&lt;/p&gt;
&lt;pre&gt;
my @select_options = ( {value =&gt; 1, label =&gt; 'One'}, 
       {value =&gt; 2, label =&gt; 'Two'}, {value =&gt; 3, label =&gt; 'Three'} );
my $args =  {
    name       =&gt; 'test',
    field_list =&gt; [
        'username' =&gt; {
            type  =&gt; 'Text',
            apply =&gt; [ { check =&gt; qr/^[0-9a-z]*/, message =&gt; 
                   'Contains invalid characters' } ],
        },
        'password' =&gt; {
            type =&gt; 'Password',
        },
        'a_number' =&gt; {
            type      =&gt; 'IntRange',
            range_min =&gt; 12,
            range_max =&gt; 291,
        },
        'a_select' =&gt; {
            type    =&gt; 'Select',
            options =&gt; \@select_options,
        },
        'sub' =&gt; {
            type =&gt; 'Compound',
        },
        'sub.user' =&gt; {
            type  =&gt; 'Text',
            apply =&gt; [ { check =&gt; qr/^[0-9a-z]*/, 
               message =&gt; 'Not a valid user' } ],
        },
        'sub.name' =&gt; {
            type  =&gt; 'Text',
            apply =&gt; [ { check =&gt; qr/^[0-9a-z]*/, 
                message =&gt; 'Not a valid name' } ],
        },
        'submit' =&gt; {
            type =&gt; 'Submit',
        },
    ]
};
my $form = HTML::FormHandler-&gt;new( %$args );
&lt;/pre&gt;
&lt;p&gt;And of course you can use one of the rendering roles, HTML::FormHandler::Render::Simple, or the rendering widgets, or write your own renderer... Too Many Ways To Do Things (tm).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-2794221169944718137?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/2794221169944718137/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=2794221169944718137' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/2794221169944718137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/2794221169944718137'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2010/02/creating-formhandler-form-from.html' title='creating a FormHandler form from a DBIx::Class result source'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-7282248860179428413</id><published>2009-08-26T10:48:00.003-04:00</published><updated>2009-08-26T11:20:04.959-04:00</updated><title type='text'>Moose: adding attributes to a base class</title><content type='html'>&lt;p&gt;I'm using FormHandler for an example here, but the technique is general.&lt;/p&gt;
&lt;p&gt;FormHandler forms are Perl classes with a number of attributes including an array of Field classes with another (probably too large) number of attributes. A few of the field attributes are validation and data related, but a lot of the other ones are related to producing HTML for display. Despite the too many attributes in the field classes, users still want yet more attributes. One of the FormHandler users was developing forms that used a javascript form package and wanted to interface the FormHandler forms to the javascript forms. To do this, he wanted an additional attribute in the fields to store information that would be used by extJs.&lt;/p&gt;
&lt;p&gt;One possibility would be to subclass every last single field and add an additional attribute. This does not sound like either fun or a good idea. A much better alternative was to use Moose to add attributes to the base class by applying a role containing the attributes.&lt;/p&gt;
&lt;p&gt;So I started out by creating a small role containing a single attribute:&lt;/p&gt;
&lt;pre&gt;
   package MyApp::Field::Extra;
   use Moose::Role;
   has 'my_extra_attribute' =&gt; (is =&gt; 'rw', isa =&gt; 'Str' );
   1;
&lt;/pre&gt;
&lt;p&gt;Now I needed someplace to apply the role. The BUILD method of the user form looks like a good place. Like good Moose classes, all of the fields have '__PACKAGE__-&gt;meta-&gt;make_immutable' in them. So in order to apply a role we have to temporarily make the class mutable and then make it mutable again. So I make the class mutable, apply the role using Moose::Util, then make it immutable again:&lt;/p&gt;
&lt;pre&gt;
   my $class = 'HTML::FormHandler::Field';
   $class-&gt;meta-&gt;make_mutable;
   Moose::Util::apply_all_roles( $class-&gt;meta, ('MyApp::Field::Extra'));
   $class-&gt;meta-&gt;make_immutable;
&lt;/pre&gt;
&lt;p&gt;Using a test file I make a form class using this code in the BUILD method, create an instance of the form, and find that the fields now have an additional attribute that I can retrieve and set.&lt;p&gt;
&lt;p&gt;This looks good until I try to set the new attribute in a 'has_field' declaration:&lt;/p&gt;
&lt;pre&gt;
   has_field 'my_field' =&gt; ( my_extra_attribute =&gt; 'some_value' );
&lt;/pre&gt;
&lt;p&gt;Ooops. This doesn't work. I'd forgotten that the fields are constructed in the base class BUILD method which fires before my form class's BUILD method. So now I need someplace else to move my role setting that will happen before the base class BUILD. Maybe after BUILDARGS...&lt;/p&gt;
&lt;pre&gt;
   after 'BUILDARGS' =&gt; sub {
      my $class = 'HTML::FormHandler::Field';
      $class-&gt;meta-&gt;make_mutable;
      Moose::Util::apply_all_roles( $class-&gt;meta, ('MyApp::Field::Extra'));
      $class-&gt;meta-&gt;make_immutable;
   };
&lt;/pre&gt;
&lt;p&gt;This works. Now I can treat the new attribute just like an original field attribute. And it's a lot easier than subclassing every field...&lt;/p&gt;
&lt;p&gt;There are other ways of achieving the same thing. You could add an attribute instead of applying a role. But roles are more general purpose and flexible, so I'm satisfied with this solution for now.&lt;/p&gt;
&lt;p&gt;And I definitely &lt;3 the flexibility that comes with Moose.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-7282248860179428413?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/7282248860179428413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=7282248860179428413' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/7282248860179428413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/7282248860179428413'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2009/08/moose-adding-attributes-to-base-class.html' title='Moose: adding attributes to a base class'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-8329655638320537240</id><published>2009-08-02T11:48:00.002-04:00</published><updated>2009-08-02T12:15:45.835-04:00</updated><title type='text'>Fields: Moose attributes or arrays of objects?</title><content type='html'>&lt;p&gt;Moose attributes are lovely things. They're a part of Moose that helps to make programming fun again. But having a magical, Dr. Who screwdriver doesn't mean that you can lose all of your other tools.  If you have a nail, a good old-fashioned hammer is the right tool.&lt;/p&gt;

&lt;p&gt;Moose type constraints are great things to catch programmer errors, typos, incorrect objects. Throwing errors for this kind of type failure is a good thing. You want the programmer to notice that something has gone wrong even if he hasn't had his morning coffee. I first did object oriented programming with C++. I still remember all the hoops that we had to jump through to handle construction time errors (many C++ compilers didn't have exceptions yet). The problem of what to do if you can't create a valid object is the problem that Moose attributes are designed to solve, and throwing errors is the proper thing to do.&lt;/p&gt;

&lt;p&gt;But in my opinion, when the task is validation, &lt;i&gt;not&lt;/i&gt; construction of a valid object, throwing errors isn't always the best way. You want to take an input string, hand it to the validator which examines it and hands it calmly back saying "good" or "not good", or some more specific error message which can be presented to a user--a user who is &lt;i&gt;not&lt;/i&gt; the programmer. Handing it to a construct which instead has a tantrum and throws it back at your head - picture the programmer frantically dodging this way and that, trying to catch the message and de-cipher the problem to present some reasonable message to the user - introduces unnecessary difficulties.&lt;/p&gt;

&lt;p&gt;When I started doing the work that turned into HTML::FormHandler I looked at the possibility of turning the field objects into Moose attributes, and saw a number of problems. One of the problems was simply names. Any attribute in the form that was not a field became a name that was not allowed as a field name. This sucked. Of course the programmer could pick some other name and have some additional attribute trait that specified the "real" field name. Yuck, but I suppose it would have worked.&lt;/p&gt; 

&lt;p&gt;There was a lot of functionality in the field class already, so it seemed to make most sense to have the attributes be of a field object type. But then the Moose attribute type validation doesn't actually apply to the job of the field classes -- validation -- but instead to whether or not this is a valid field, which is appropriate but not the same thing at all. Moving all of the attributes in the field class into some Moose attribute metaclass didn't appeal at all. I didn't see the point. The fields worked fine as objects. If you didn't ever want to provide assistance in constructing HTML or allow validation using simple object methods or an endless list of other things, I suppose you could go in that direction. But I already had working code and working functionality that I liked that I wasn't willing to give up for no reason other than ... um, fashion? Mooseish purity?&lt;/p&gt;

&lt;p&gt;So there would be a bunch of Moose attributes that had a field class type. Then you need to be able specify all of the attributes to use to construct the fields. This is not insurmountable, but to do it in a non-irritating way (for me) would require some Moose-ish sugar. Fine, that would work. The next problem is that the fields are really a kind of set and you often need to iterate over them. So there would need to be some kind of array (or other collection) pointing to all of these objects. This was starting to look suspiciously like the array of field objects that I already had.&lt;/p&gt;

&lt;p&gt;At this point I started wondering what &lt;i&gt;advantage&lt;/i&gt; there was to making the fields Moose attributes. Sure, you could do $form-&gt;&lt;field_name&gt; sometimes. If the field name didn't conflict with other attributes. But I was already planning to have nested sub-fields and arrays of repeatable fields and that model didn't fit well at all with the Moose attribute idea. It's not like it was necessary to be able to do method modifiers or other Moose-ish things on the fields. They were objects. You could do whatever you wanted in them already. You could already use method modifiers (etc) on all of the parts of the form validation process.&lt;/p&gt;

&lt;p&gt;I'm sure there would have been some way of making fields-as-Moose-attributes work. But this is Just A Program. The idea is to make it work in as simple a way as possible (but no simpler), not to make sure that it uses the latest shiny thing whether it provides any advantage or not. (Well, that's my goal anyway. Your goal may be playing with shiny new technologies and tools. :) )&lt;/p&gt;

&lt;p&gt;The Collection::Array of field objects was working fine. It's still working fine. I still don't see any advantage to turning the fields into Moose attributes that isn't canceled out by some other disadvantage or complication. The current architecture, which I'm happy with, would be just silly shoehorned into a bunch of Moose attributes.&lt;/p&gt;

&lt;p&gt;I guess I won't win the Most Unnecessary Moose Metaprogramming (MUMM) award (which it sometimes seems to me that the Mooserati are competing for). Shrug.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-8329655638320537240?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/8329655638320537240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=8329655638320537240' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/8329655638320537240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/8329655638320537240'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2009/08/fields-moose-attributes-or-arrays-of.html' title='Fields: Moose attributes or arrays of objects?'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-1188890649359659242</id><published>2009-07-18T07:59:00.006-04:00</published><updated>2009-07-18T16:12:22.562-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl formhandler programming'/><title type='text'>why HTML::FormHandler...</title><content type='html'>&lt;p&gt;Dan Dascalescu (dandv) said about FormHandler that it "would be awesome if the POD could mention what's different from FormFu, why create the module at all." I have tried to put some of that into the pod, but apparently it's not enough. So I've been thinking about this issue (the problem of too many packages and not enough info on the differences), and I think that there's are a number of things getting in the way of being clear enough and loud enough with "what's different".&lt;/p&gt;
&lt;p&gt;For one thing, Carl Franks and many other people have put lots of work and time into FormFu and like it. The reasons that HTML::FormHandler exists are personal, very human feelings and reactions that don't belong in "official documentation". In order for the statements about what I think to not be offensive, they have to be put into the form of: "This is the way I feel, this is the way I reacted. YMMV." I don't want to start a flame war and I don't want to hurt anybody's feeling. (Yeah, I know that's kinda girly. So sue me.)&lt;/p&gt;
&lt;p&gt;The next problem is that &lt;i&gt;I don't really know FormFu&lt;/i&gt;. When I was looking for a form package a year and a half ago I looked at it and I just could not bring myself to use it. I hated it on sight. So I'm not competent to compare FormHandler and FormFu. (Anybody willing to submit a doc patch who &lt;i&gt;has&lt;/i&gt; used FormFu?)&lt;/p&gt;
&lt;p&gt;The last problem is that I don't think that I'm necessarily the right person to be really loud and clear about the advantages of FormHandler. I'm too close to it. It would feel like I'm tooting my own horn, boasting. I'm almost certainly not going to be seeing its weaknesses clearly. I think that somebody else will have to make the definitive comparison.&lt;/p&gt;
&lt;p&gt;I guess I &lt;i&gt;can&lt;/i&gt; talk about why FormHandler exists, but many of the reasons are human reasons, not technical reasons.&lt;p&gt;
&lt;p&gt;Programmers have emotions, sometimes strong emotions, about the tools and libraries that they use. Some packages are clean, easy, fun. Modifications can be made easily. The pieces can be clumped together in ways that are accessible and readable. Programmers can have strong emotions about &lt;i&gt;variable names&lt;/i&gt;. So clearly they're a little unbalanced. (You should have seen the arguments that me and my manager had about whether a database column should be named 'report_no' or 'report_num'. It was downright silly but we both had emotions that were too strong to give up our positions. About a database &lt;i&gt;column name&lt;/i&gt;.) Sometimes the emotions are irrational, or intuitions based on experience that can't easily be put into words.&lt;/p&gt;
&lt;p&gt;So I'm trying to remember why I looked at FormFu and thought: "Yuck. I'm not going to use that. No, no, no." (Warning: this may not be helpful to you in making a choice of packages.)&lt;p&gt;
&lt;p&gt;The first problem that I had with FormFu was the yaml config files. I hate YAML. With a passion. I think that whitespace sensitive formats are stupid. I hated hated hated the tab-sensitivity of make files, and YAML was just more of the same. My eyes/brain can't adjust to pulling out the significant information when I glance over a YAML file. Yes, I KNOW that FormFu can use any kind of Config::General format. But all of the documentation was in YAML and I Didn't Want to Look at It.&lt;/p&gt;
&lt;p&gt;There. I &lt;i&gt;told&lt;/i&gt; you this wasn't going to be a rational technical discussion, didn't I?&lt;/p&gt;
&lt;p&gt;I also hated the fact that the forms were even defined in config files to start with. I looked at it, and my first thought was: but what if I want to do something in a way that hasn't been pre-defined? Yes, I know you can make your own constraint classes, yadda, yadda, yadda. It was too disconnected to the particular form. I looked at the way it worked and I got claustrophobia. I felt like I would be having to adapt myself to FormFu, instead of me being able to adapt FormFu to the way I wanted to work. FormFu code couldn't be easily subclassed or overridden for a particular form. You'd have to do something weird to change the way that it worked. I have no idea if my reaction was accurate or not. I couldn't bring myself to try it enough to find out.&lt;/p&gt;
&lt;p&gt;It felt heavyweight, cumbersome, and rigid. And no, I can't give you detailed list of why it felt that way to me. I read the documentation and listened to people complain in #catalyst, and that was it.&lt;/p&gt;
&lt;p&gt;Speaking of #catalyst, that was a big source of my dislike for FormFu. Lots of people showed up trying to do something particular with HTML and could &lt;i&gt;not&lt;/i&gt; figure out how to do it. I saw people spend days on HTML changes that would have taken them minutes by hand. I saw how hard it was to figure out how to achieve particular results (that I can't remember anymore). This may be totally unfair of me. Maybe boatloads of people will eventually show up complaining about FormHandler in the same way. But I'm trying to be honest here (painfully so, maybe). And those complaints did play a part in my disinclination to use a package that was so hard to customize.&lt;/p&gt;
&lt;p&gt;So I looked at the other options out there. Formbuilder was deprecated. Rose Forms was ok, but not quite right. Reaction was interesting but overkill for my application. I found Form::Processor, and it certainly wasn't perfect, but at least the thought of using it didn't depress me. I liked the architecture and I liked the way that it could automatically save forms to the database. The problem was that it didn't have a DBIC model. I decided to write one.&lt;/p&gt;
&lt;p&gt;Unfortunately Form::Processor had almost no tests. It had a few field tests, and a small handful of non-database form tests. There were NO tests for interfacing with the database. There were no &lt;i&gt;examples&lt;/i&gt; for interfacing with the database. So the first thing I had to do was create a CDBI example so that I could figure out how a DBIC model would work. Eventually I got the DBIC model to work, and uploaded my first package to CPAN. They did not come and arrest me for inadequate code.&lt;/p&gt;
&lt;p&gt;I was happy enough with Form::Processor for quite a while. Then I started to use Moose in most of my new code. Form::Processor used Rose::Object. I really liked Moose and it seemed silly to be using two different object systems. The Form::Processor code, because it used Rose::Object, looked easy to convert to Moose. So in a burst of energetic yak shaving, I converted it to Moose.&lt;/p&gt;
&lt;p&gt;Bill Moseley, the owner of Form::Processor, had some interest in moving toward Moose, but he didn't have time to work on it. There was no public repository. He had a suite of tests he wanted it to pass that I didn't have access to. There were many Moose features that couldn't be used and feature improvements that couldn't be done because they wouldn't be compatible with Bill's codebase.&lt;/p&gt;
&lt;p&gt;I was getting some interest in a Moosified form processor from other programmers and I liked how my new code was shaping up. 
So I put the code up on github and released it to CPAN. Followed by deafening silence. But I had been communicating with Zbigniew Lukasiak about the new project and he had lots of experience with FormFu and ideas he wanted to try out, so he joined the project, which was a godsend. It's so much better to have other progammers contributing too.&lt;/p&gt;
&lt;p&gt;So now it's six months from the first CPAN release. I've gotten a lot of positive feedback from people who've used it who like it. The codebase feels more stable now and we've implemented most of the large features we had in mind (though we're hoping for better rendering in the future...)&lt;/p&gt;
&lt;p&gt;We've tried hard to make the API consistent, we've refactored to support compound and repeatable fields. We have a comprehensive test suite. It still seems to be very easy to customize - Moose helps with that. To me, it feels flexible, not cumbersome and rigid. You can use hand-built HTML if you want. The rendering is straightforward and simple to a fault. Adding new features has not been painful. I'm happy with it. YMMV.&lt;/p&gt;
&lt;p&gt;I suspect that this was NOT what Dan had in mind with his request for 'why create the module at all'. It might be of more interest to a sociologist studying open source than somebody looking for reasons to pick a package. But it is the answer that I have, such as it is.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-1188890649359659242?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/1188890649359659242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=1188890649359659242' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/1188890649359659242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/1188890649359659242'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2009/07/why-htmlformhandler.html' title='why HTML::FormHandler...'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-1888125830639019226</id><published>2009-07-18T07:18:00.002-04:00</published><updated>2009-07-18T07:36:29.509-04:00</updated><title type='text'>Perl Blogging for personal satisfaction</title><content type='html'>&lt;p&gt;Okay, so I suck at dealing with certain sorts of motivational programs. In another persona I write fiction. Fiction writers have this quaint concept BIAW - Book In a Week. It's not really a book in a week. It's a group of writers who get together and commit to some writing goal in the beginning, and then cheer each other on, or boo and hiss. Whatever. It's SUPPOSED to be motivational. The idea is that committing yourself to a public goal like that is supposed to motivate you to actually do it, since you will (theoretically) be ashamed of not meeting your goal. Or be inspired by the achievements of others. Or something.&lt;/p&gt;
&lt;p&gt;I tried joining these sorts of BIAW programs on multiple occasions. And then I noticed something odd. I was writing MORE when I &lt;i&gt;wasn't&lt;/i&gt; enrolled in some BIAW program than when I was. Sigh.&lt;/p&gt;
&lt;p&gt;Apparently I'm not inspired enough by the idea of not achieving what I said I would in front of other people. It actually has a *cough* negative affect. I blow off a day, and then I start resenting the whole thing. It becomes a chore, a drag, some irritating task that I'm "supposed to" be doing. It's not fun anymore.&lt;/p&gt;
&lt;p&gt;And the Perl ironman thing has started to have the same feeling for me. Not the fault of the idea. The idea is great. It's just me and the idea that don't get along.&lt;/p&gt;
&lt;p&gt;So in an attempt to actually fulfill the spirit of the Ironman challenge (as opposed to the &lt;i&gt;rules&lt;/i&gt; - ewww, rules, I hate rules) henceforth I'm not going to even TRY to meet the rules for achieving the various IronPerson levels. Instead - *gasp* - I'm going to blog about Perl and programming when I feel like I have something to say. The habit has started - and that was the whole point, after all.&lt;/p&gt;
&lt;p&gt;Now the only remaining question is ... can I think of some clever riff on Ironman for my personal perl blogging program? Um ... the MarshmallowMan? I know! the StayPuftMan!&lt;/p&gt;
&lt;p&gt;Now that I have an inspiring symbol and everything, I can stop. I'm happy now.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-1888125830639019226?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/1888125830639019226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=1888125830639019226' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/1888125830639019226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/1888125830639019226'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2009/07/perl-blogging-for-personal-satisfaction.html' title='Perl Blogging for personal satisfaction'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-6420595720389473991</id><published>2009-06-30T09:40:00.003-04:00</published><updated>2009-06-30T10:06:05.083-04:00</updated><title type='text'>Refactoring with roles for testing</title><content type='html'>&lt;p&gt;The programming I've been doing lately is very straightforward Perl. It's hard to think what might be interesting about it... and I don't want to look like an idiot and blather on about something that everybody else was doing in kindergarten.&lt;/p&gt;
&lt;p&gt;So maybe this is nothing exciting, but it's what I was doing yesterday.&lt;/p&gt;
&lt;p&gt;I'm working on replacing an ancient grew-up-over-seventeen-years Perl backend system with more modern Perl. Instead of using a database for most of it, information on state and status is encoded in Linux file permissions and empty files, and in strings in files. Etc. Etc. I'm updating a large portion of it to use a semi-real database (MySQL - but in this case it really is a step upward), but I'm a one person programming team and it just wasn't feasible to rewrite the whole system in one project. As it is, the project was really too big for one person, but it just wasn't possible to do a decent job without completely re-doing a fairly large chunk.&lt;p&gt;
&lt;p&gt;So I get to an interface to a part of the old system, where instead of just storing some flags in the database I have to write an empty file in one directory for one state, copy a file to a different directory for another state, append a line with an identifier in it to a file for a third state... You get the idea.&lt;p&gt;
&lt;p&gt;At this point it's not clear whether the section I'm interfacing to will ever be rewritten. The higher-ups have gotten pretty twitchy at how much this is costing, and I'll probably have to work on some PHP project part time in the fall. So I don't know if this interface code will ever be used in any other module. But it's irritating stuff to test and debug because it's used in the middle of a fairly long and complex process.&lt;p&gt;
&lt;p&gt;So I plopped it all into a Moose role and created a test case with a dummy package:&lt;p&gt;
&lt;pre&gt;
   use Test::More tests =&gt; 3;
   
   {
      package Test::SomeInterface;
      use Moose;
      with 'Some::Kludgy::Interface';
   }
   my $test = Test::SomeInterface-&gt;new;
   ok( $test, 'it compiled!' );
   ok( $test-&gt;process, 'it didn't blow up!' );
   ok( $test-&gt;some_status, 'it worked!' );
&lt;/pre&gt;
&lt;p&gt;So now the funky interface code is packaged off by itself and easily replaced, it was much easier to test than buried in some larger module, and if I'm lucky I'll never have to look at it again.One nice side effect of doing this was that I was forced to clean up what I was passing in to the methods instead of relying on the fairly global object attributes.&lt;p&gt;
&lt;p&gt;Pretty obvious, I guess. But it's yet another way in which Moose makes programming more bearable - when fun is too much to hope for. I &lt;3 Moose.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-6420595720389473991?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/6420595720389473991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=6420595720389473991' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/6420595720389473991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/6420595720389473991'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2009/06/refactoring-with-roles-for-testing.html' title='Refactoring with roles for testing'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-9149578522520618658</id><published>2009-06-16T00:37:00.005-04:00</published><updated>2009-06-20T18:29:08.690-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='FormHandler'/><category scheme='http://www.blogger.com/atom/ns#' term='perl formhandler programming'/><title type='text'>Where the cleaver falls...</title><content type='html'>Way back in the dark ages, I worked on one of the first projects at IBM to use that fancy new methodology, object oriented programming. They sent the whole team to a month of OO training, and then that wasn't quite enough to bring us up to speed, so they sent us to another month with a different traning company. I remember that one month used a well-regarded (at that time) book by Grady Booch. The whole object thing wasn't that hard to understand, but the thing that I couldn't quite wrap my mind around was how you figured out what to make the objects, how to split up the problem domain into pieces. So I eagerly flipped through the Booch book, thinking that they must have some words of wisdom on this point, and finally I found it. Buried somewhere in the middle they had one page with three paragraphs which basically said: and then a miracle occurs.
&lt;br /&gt;
&lt;br /&gt;
Pretty much the equivalent of the humorous saying somebody I know was fond of: Where the cleaver falls, there the chicken parts. (Maybe you had to be there...)
&lt;br /&gt;
&lt;br /&gt;
So I was working on a comment screen that needed a captcha. I had never used one before, but I figured it couldn't be that hard. HTML::FormHandler is a form processor, and a captcha is a form element, so it seemed obvious that a captcha field for HFH was in order. That part was easy... And then I realized that in order to check the value typed in by the user, the captcha had to be stored in the session. The session (in this case) is managed by a Catalyst plugin, and for the form field to be aware of the session just seems wrong. Too much mixing of areas of concern. 
&lt;br /&gt;
&lt;br /&gt;
So a Moose role comes to the rescue. (Perl!) I created a Moose role that contained the captcha field, plus provided 'get_captcha' and 'set_captcha' methods. This seems relatively clean - or at least better than having the field mess with the session. Of course in order to access the session, the Catalyst context or session needs to be passed in to the form object. Not ideal, but not all that bad either. But now these methods are form methods... They could be turned into callbacks, or coderefs that are set on the field, but I've already had to deal with not-entirely-clean relationships between form and field before, so for now I decide to just call them as form methods. I don't really like this, because I'd prefer that the fields not know about the object that contains them, but it's easy and it works.
&lt;br /&gt;
&lt;br /&gt;
Then I realize that I'll need a URL for the image in the field. Damn. This is getting messy. I suppose that I can add yet another attribute 'captcha_url' and set THAT too. But then there's another required piece of code that's neither form nor field, but a controller action. Sigh. It's too many different pieces of code for one simple thing. 
&lt;br /&gt;
&lt;br /&gt;
Oject oriented programming is no longer the new, shiny thing that it was so long ago, but the problem of splitting up the problem into nice little pieces is still with us. That OO training was for was an early attempt at an object oriented interface to a SQL database. It failed utterly. Looking back, I have to say that the problem wasn't fully understood - or at least we didn't understand it. It was a brave attempt, but a fair amount of knowledge about the problems associated with doing ORMs has grown up, and they're better these days.
&lt;br /&gt;
&lt;br /&gt;
So I guess progress is being made. In some places by some people..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-9149578522520618658?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/9149578522520618658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=9149578522520618658' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/9149578522520618658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/9149578522520618658'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2009/06/where-cleaver-falls.html' title='Where the cleaver falls...'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-6014066871292527353</id><published>2009-06-05T10:22:00.004-04:00</published><updated>2009-06-05T11:48:49.893-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='FormHandler'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Moose'/><title type='text'>Flexible extensions with Moose method modifiers</title><content type='html'>When constructing an API for a library intended to be subclassed by users, you run into the classic tension between power and simplicity. Too many ways to call your code, too many different methods and the user is overwhelmed. Yet if you don't have enough power, the user may by stymied when he reaches some level of complexity.
&lt;br /&gt;&lt;br /&gt;
Moose method modifiers provide a lot of flexibility that doesn't necessarily have to be provided by an explicit API. In some cases they may provide stopgap ways of extending, in other cases they may actually be better than creating more complexity by providing more explicit hooks.
&lt;br /&gt;&lt;br /&gt;
The main processing method for HTML::FormHandler is pretty straightforward:
&lt;pre&gt;
sub process
{
   my $self = shift;

   $self-&gt;clear if $self-&gt;processed;
   $self-&gt;_setup_form(@_);
   $self-&gt;validate_form if $self-&gt;has_params;
   $self-&gt;update_model if $self-&gt;validated;
   $self-&gt;processed(1);
   return $self-&gt;validated;
}
&lt;/pre &gt;
The above method is called when a form is processed:
&lt;pre&gt;
   my $form = MyApp::Form::User-&gt;new;
   $form-&gt;process( item =&gt; $user, params =&gt; $c-&gt;req-&gt;params );
&lt;/pre&gt;
The form is something like:
&lt;pre&gt;
   package MyApp::Form::User;
   use HTML::FormHandler::Moose;
   extends 'HTML::FormHandler::Model::DBIC';

   has_field 'username' ( required =&gt; 1 );
   has_field 'some_attr';
&lt;/pre&gt;
A common need is to have particular fields be required in some circumstances and not in others. So maybe it would be nice to have some kind of callback to determine whether the field is required or not... But a simple Moose method modifier on one of the methods called in the 'process' routine will do the trick just fine:
&lt;pre&gt;
   before 'validate_form' =&gt; sub {
      my $self = shift;
      $self-&gt;field('some_attr')-&gt;required(1)
         if( ...some condition... );
   };
&lt;/pre&gt;
Now maybe there's some magical API syntax that could achieve the same thing, but really this is pretty straightforward and easy. Maybe there's some additional database update that you want to do that's not directly related to the fields, such as recording that the user updated his record. Another Moose method modifier comes to the rescue:
&lt;pre&gt;
   before 'update_model' =&gt; sub {
      shift-&gt;item-&gt;user_updated;
   };
&lt;/pre&gt;
...where 'user_updated' is a method on your DBIx::Class result source that sets a flag or an updated time or whatever you want.
The same result could be achieved by subclassing the methods of course, but the method modifiers can also be used in Moose roles, making it possible to split up your form pieces into nice chunks that can be reused in multiple forms.
&lt;pre&gt;
   package MyApp::Form::Options;
   use HTML::FormHandler::Moose::Role;

   has_field 'opt_in';
   has_field 'something_else';
   after 'validate' =&gt; sub {
      ...do some specific cross validation...
   };
   before 'update_model' =&gt; sub {
      ...some db processing...
   };
&lt;/pre&gt;
And then a form class could just be a collection of roles:
&lt;pre&gt;
   package MyApp::Form::User;
   use HTML::FormHandler::Moose;
   extends 'HTML::FormHandler::Model::DBIC';
   with 'MyApp::Form::Options';
   with 'MyApp::Form::Login';
   1;
&lt;/pre&gt;
So the power and flexibility of HTML::FormHandler's API are increased without extra code simply by using Moose and its method modifiers. When I was originally hired to program in Perl I wasn't that happy about it, partly because the native Perl OO features are weak and kludgy. But with Moose that's a thing of the past. Perl + Moose are as good as or better than any other object oriented language I've worked with.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-6014066871292527353?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/6014066871292527353/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=6014066871292527353' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/6014066871292527353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/6014066871292527353'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2009/06/flexible-extensions-with-moose-method.html' title='Flexible extensions with Moose method modifiers'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-4016062547270263723</id><published>2009-05-27T14:20:00.002-04:00</published><updated>2009-06-05T11:50:28.357-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='FormHandler'/><category scheme='http://www.blogger.com/atom/ns#' term='Moose'/><title type='text'>Validating structured data</title><content type='html'>In an earlier post I discussed how HTML form processing, when sufficiently generalized, leads to processing structured data (by which I mean data in Perl-ish hashes and lists). Here is an example of some structured data:
&lt;pre&gt;
my $user_record = {
   username =&gt; 'Joe Blow',
   occupation =&gt; 'Programmer',
   tags =&gt; ['Perl', 'programming', 'Moose' ],
   employer =&gt; {
      name =&gt; 'TechTronix',
      country =&gt; 'Utopia',
   },
   options =&gt; {
      flags =&gt; {
         opt_in =&gt; 1,
         email =&gt; 0,
      },
      cc_cards =&gt; [
         {
            type =&gt; 'Visa',
            number =&gt; '4248999900001010',
         },
         {
            type =&gt; 'MasterCard',
            number =&gt; '4335992034971010',
         },
      ],
   },
   addresses =&gt; [
      {
         street =&gt; 'First Street',
         city =&gt; 'Prime City',
         country =&gt; 'Utopia',
         id =&gt; 0,
      },
      {
         street =&gt; 'Second Street',
         city =&gt; 'Secondary City',
         country =&gt; 'Graustark',
         id =&gt; 1,
      },
      {
         street =&gt; 'Third Street',
         city =&gt; 'Tertiary City',
         country =&gt; 'Atlantis',
         id =&gt; 2,
      }
   ]
};

&lt;/pre&gt;
Here is the &lt;a href="http://search.cpan.org/~gshank/HTML-FormHandler/"&gt;HTML::FormHandler&lt;/a&gt; form that defines field validators to process that structure:
&lt;pre&gt;
{
   package Structured::Form;
   use HTML::FormHandler::Moose;
   extends 'HTML::FormHandler';

   has_field 'username';
   has_field 'occupation';
   has_field 'tags' =&gt; ( type =&gt; 'Repeatable' );
   has_field 'tags.contains' =&gt; ( type =&gt; 'Text' );
   has_field 'employer' =&gt; ( type =&gt; 'Compound' );
   has_field 'employer.name';
   has_field 'employer.country';
   has_field 'options' =&gt; ( type =&gt; 'Compound' );
   has_field 'options.flags' =&gt; ( type =&gt; 'Compound' );
   has_field 'options.flags.opt_in' =&gt; ( type =&gt; 'Boolean' );
   has_field 'options.flags.email' =&gt; ( type =&gt; 'Boolean' );
   has_field 'options.cc_cards' =&gt; ( type =&gt; 'Repeatable' );
   has_field 'options.cc_cards.type';
   has_field 'options.cc_cards.number';
   has_field 'addresses' =&gt; ( type =&gt; 'Repeatable' );
   has_field 'addresses.street';
   has_field 'addresses.city';
   has_field 'addresses.country';
   has_field 'addresses.id';

}

&lt;/pre&gt;
The names of the fields are flattened references to the elements of the structure, with special field types for Repeatable and Compound elements. These types of structures can be used to update a database with DBIx::Class (although there are limits, of course).
&lt;br /&gt;
&lt;br /&gt;
I've left off the actual validators, but they can be defined pretty easily using Moose types or other constraints.
&lt;pre&gt;
  has_field 'cc_type' =&gt; ( apply =&gt; [ CCType ] );
&lt;/pre&gt;
It would probably be better to define some of the fields in a role or field, to keep some of the related validation in the same place. The validation of the credit card numbers depend on the type of the credit card, for example.

Error messages can be retrieved from an array of error fields or plain error messages, but there need to be more flexible ways of getting those messages. I'm not exactly sure what people will want yet.
&lt;br /&gt;
&lt;br /&gt;
Real Soon Now (tm) I'm going to work on a KiokuDB model... So many programming tasks, so little time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-4016062547270263723?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/4016062547270263723/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=4016062547270263723' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/4016062547270263723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/4016062547270263723'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2009/05/validating-structured-data.html' title='Validating structured data'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-4920166604025289663</id><published>2009-05-19T14:01:00.003-04:00</published><updated>2009-06-05T11:50:47.372-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Complexity happens</title><content type='html'>I've heard a programmer's job described as 'managing complexity'. People who like programming tend to like other complex systems, like, say D&amp;D. (They also like fantasy in general... no doubt there's some clever comment there that my cold-fogged brain can't work out.)
&lt;br /&gt;
&lt;br /&gt;
And yet, one of the primary goals in a programming project is to keep it simple. (Otherwise known as KISS.) So there's this continual tension between simplicity and complexity. Simplicity in one area may require complexity in another. Creating a simple, easy-to-use API often requires more underlying complexity than a non-intuitive but straightforward interface. Though there are occasionally golden moments when things fall into place and you can achieve both greater simplicity of interface AND greater code simplicity. Just don't hold your breath waiting for them...
&lt;br /&gt;
&lt;br /&gt;
Problems that seem simple to start with acquire complexity when you add features, when you handle more use cases. Simple, stupid things like the fact that you don't get anything in CGI parameters for an un-checked checkbox introduce irregularities that flow through to surprising corners of code. Decisions made about what it means to not have a particular parameter or have it set to empty cascade through formerly pristine and clean lines of code.
&lt;br /&gt;
&lt;br /&gt;
I'm not quite sure whether this is a complaint or simply a report. Sometimes the logical complexity is fascinating. You poke something to see what happens; you try some new way of factoring to see if that magical moment of greater order occurs... And then sometimes you can hardly stay awake and certainly can't concentrate, and you find yourself surfing Amazon for some new fantasy novel that's a lot more your speed.
&lt;br /&gt;
&lt;br /&gt;
Or desperately trying to think of something to write that's somehow remotely related to Perl programming. Because you foolishly committed to DOING THAT in a moment of insanity.
&lt;br /&gt;
&lt;br /&gt;
Let me just repeat that key phrase a couple of more times, in case foolish sites that count dumb things and claim they mean something aren't paying attention:  Perl programming Perl programming Perl programming
&lt;br /&gt;
&lt;br /&gt;
Thanks. I'm done blathering now. I think I've got enough of a word count.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-4920166604025289663?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/4920166604025289663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=4920166604025289663' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/4920166604025289663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/4920166604025289663'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2009/05/complexity-happens.html' title='Complexity happens'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-2973470207098596070</id><published>2009-05-12T08:46:00.007-04:00</published><updated>2009-06-05T11:51:55.947-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FormHandler'/><title type='text'>Defining the form processing problem</title><content type='html'>This week I've been discussing the goals of a form processor and working on adding support to HTML::FormHandler for multiple rows. When I first started doing web programming and learning Perl 18 months ago, I looked for a module that did what I wanted, and thought "it can't be that hard". Once I got into it, the problem started to look more and more complex. You need to map different representations of data onto each other, each level having different kinds of relationships to each other, and yet maintain the accessibility of the information from multiple representations. 
&lt;br /&gt;
&lt;br /&gt;
Let's start with a Perl-ish structure of hashes and lists:
&lt;pre&gt;

{
   addresses =&gt; [
      {
         city =&gt; 'Middle City',
         country =&gt; 'Graustark',
         address_id =&gt; 1,
         street =&gt; '101 Main St',
      },
      {
         city =&gt; 'DownTown',
         country =&gt; 'Utopia',
         address_id =&gt; 2,
         street =&gt; '99 Elm St',
      },
      {
         city =&gt; 'Santa Lola',
         country =&gt; 'Grand Fenwick',
         address_id =&gt; 3,
         street =&gt; '1023 Side Ave',
      },
   ],
   'occupation' =&gt; 'management',
   'user_name' =&gt; 'jdoe',
}

&lt;/pre&gt;
This structure represents a user with a user name, an occupation, and an array of addresses. This example includes an array of hashrefs, because that's what I'm working on this week...  The first problem is that this structure can't be directly represented in CGI/HTTP parameters, since they don't do nested hashrefs. So in order to get this structure into and out of an HTML form, we flatten it into a hashref with names that can be munged by something like CGI::Expand:
&lt;pre&gt;
my $params = {
   'addresses.0.city' =&gt; 'Middle City',
   'addresses.0.country' =&gt; 'Graustark',
   'addresses.0.address_id' =&gt; 1,
   'addresses.0.street' =&gt; '101 Main St',
   'addresses.1.city' =&gt; 'DownTown',
   'addresses.1.country' =&gt; 'Utopia',
   'addresses.1.address_id' =&gt; 2,
   'addresses.1.street' =&gt; '99 Elm St',
   'addresses.2.city' =&gt; 'Santa Lola',
   'addresses.2.country' =&gt; 'Grand Fenwick',
   'addresses.2.address_id' =&gt; 3,
   'addresses.2.street' =&gt; '1023 Side Ave',
   'occupation' =&gt; 'management',
   'user_name' =&gt; 'jdoe',
};
&lt;/pre&gt;
A corollary of this is that the form processing program should be able to take in structures of either type, and output at least the flattened structure so that it can be used to fill in the form with current data. Then we consider where the initial data is going to come from. Often the data is in a database, so now we have the problem of taking a database object, like a 'user' row with a relationship pointing to a number of addresses, and convert it to the flat CGI hash. And we also want to go in the opposite direction, converting a flat CGI hash into a structure suitable for putting back into the database. The data in a database (or other data soruce) isn't necessarily in a form suitable for displaying as strings in an HTML form. So there are inflation and deflation steps. The database structure and data must be mapped to a CGI structure.
&lt;br /&gt;&lt;br /&gt;
Then there's the question of how to define the validators which are the main purpose of this exercise. The data that's input from the parameters passed in must be validated (and/or inflated). If there are errors, the program has to present that information in such a way that an HTML form can be constructed with the errors presented to the user for correction.
&lt;br /&gt;&lt;br /&gt;
There are a number of choices to be made about how to define the fields to allow these validations and conversions to happen in a simple and regular fashion. A common solution is to treat the nested elements as subforms, but they are not actually separate forms, they are simply ... nested elements.
&lt;br /&gt;&lt;br /&gt;
The way that feels best to me is to allow the definition to be done in one 'form' class, which represents one HTML form.
&lt;pre&gt;
   package HasMany::Form::User;
   use HTML::FormHandler::Moose;
   extends 'HTML::FormHandler::Model::DBIC';

   has_field 'user_name';
   has_field 'occupation';

   has_field 'addresses' =&gt; ( type =&gt; 'Repeatable' );
   has_field 'addresses.address_id' =&gt; ( type =&gt; 'PrimaryKey' );
   has_field 'addresses.street';
   has_field 'addresses.city';
   has_field 'addresses.country';
&lt;/pre&gt;
This flat representation matches the flatness of the HTML form. The field names with dots give information to allow the creation of nested elements. The field names are also related to the database object, where 'addresses' is the DBIC relationship accessor, and street/city/country are columns in the address table. In practice there would be more to these field definitions, since there would be validators associated with them, but I'll leave them out for now to simplify the problem.
&lt;br /&gt;&lt;br /&gt;
Constructing the arrays is tricky. The form object doesn't know how many elements are in the array until it is handed the information from the database or the parameters from the form. So the arrays of address fields must be cloned from the fields that have been defined and put into some structure to hold the definitions and the data. There is a choice of structures here. We can either match the &lt;pre&gt; 'addresses.1.country' =&gt; 'Utopia' &lt;/pre&gt; format, or match the &lt;pre&gt; { addresses =&gt; []}&lt;/pre&gt; structure. These structures have different numbers of levels, since we have to add the ".1." level to indicate the array. It could be set up either way and mapped to the other. For the purposes of constructing HTML, however, you want to have some place to act as a container for an individual address so that it can be wrapped in a div, so the structure with the numbered level seems more useful.
So now the 'HasMany' field container will create an array of field container objects (instances) that contain an address record.
&lt;br &gt;&lt;br /&gt;
Once constructed and filled, the nested fields can be accessed with &lt;pre&gt; $form-&gt;field('addresses')-&gt;field('1')-&gt;field('city')-&gt;value&lt;/pre&gt; or using the shortcut method &lt;pre&gt; $form-&gt;field('addresses.1.city')-&gt;value &lt;/pre&gt;. There's something awkward about this, because it's oddly modal. The field structures are different depending on whether the form has been filled out with data or not. The implementation which I have working right now has an array of fields (the same as other non-has_many compound fields) which is cloned into subfields which are created on the fly. It would be possible, I suppose, to have a dummy subfield to contain the field definitions. I'll have to think about that one...
&lt;br /&gt;&lt;br /&gt;
In order to interface with the database object in a regular, MVC-ish way, the form program should output structured data that can be saved by the database model. Inflations may be associated with this.
&lt;br /&gt;&lt;br /&gt;
So in the end, it seems like what you end up with is program which will take structured data, process it and validate it, and return structured data. This is a much more general problem than it first appears when "all" you want to do is process an HTML form.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-2973470207098596070?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/2973470207098596070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=2973470207098596070' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/2973470207098596070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/2973470207098596070'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2009/05/defining-form-processing-problem.html' title='Defining the form processing problem'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-5049983992806196415</id><published>2009-05-04T10:59:00.005-04:00</published><updated>2009-06-05T11:51:00.791-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='Moose'/><title type='text'>Moose beginners: clear, predicate, and triggers</title><content type='html'>One of the nice things about Moose is that it adds another state for your instance variables -- whether or not the variable is actually set. With standard Perl variables you can check whether the variable is defined or undefined and true or false. In Moose the state of being undefined is different from the state of being set. In order to take advantage of this additional state you need to use the 'clearer' and 'predicate' methods for your attribute:
&lt;pre&gt;
   has 'my_var' =&gt; ( isa =&gt; 'Str|Undef', is =&gt; 'rw', 
          clearer =&gt; 'clear_my_var',
          predicate =&gt; 'has_my_var' );
&lt;/pre&gt;
Setting 'my_var' to 'undef' is different than doing 'clear_my_var'. If you set it to undefined:
&lt;pre&gt;
   $my_obj-&gt;my_var(undef);
&lt;/pre&gt;
then the predicate 'has_my_var' will return true. If you check for truth in the usual way:
&lt;pre&gt;
   if( $my_obj-&gt;my_var ) { ... }
&lt;/pre&gt;
false will be returned for both the case where the attribute has been set to undefined and has been cleared. So you have to to use the predicate method:
&lt;pre&gt;
   if( $my_obj-&gt;has_my_var ) { ... }
&lt;/pre&gt;
The predicate method will return true if 'my_var' has been set to undefined, and false if 'my_var' has been cleared.
&lt;br /&gt;
An important piece of related behavior is that a trigger on an attribute is called when you set it, whether or not you are setting it to undefined, but the trigger is not called when you do a clear. So if you have an object in which only one of two variables should have a value, you can create triggers for both of them and use clear to un-set the other variable.
&lt;pre&gt;
   has 'my_var' =&gt; ( isa =&gt; 'Str', is =&gt; 'rw',
           clearer =&gt; 'clear_my_var',
           predicate =&gt; 'has_my_var',
           trigger =&gt; sub { shift-&gt;clear_my_other_var }
   );
   has 'my_other_var' =&gt; ( isa =&gt; 'Str', is =&gt; 'rw',
           clearer =&gt; 'clear_my_other_var,
           predicate =&gt; 'has_my_other_var',
           trigger =&gt; sub { shift-&gt;clear_my_var }
   );
&lt;/pre&gt;
If you tried to set 'my_var' to undef in the trigger, you would end up in an infinite recursion, since each attempt to set the other variable would cause the trigger in that variable to fire. Another issue is whether or not you should allow a particular attribute to be set to undefined. Some attributes may need an explicit undefined state, in which case you must set your isa to 'Str|Undef', but if you don't actually need an undefined state then you are better off not allowing it and using a predicate, in which case you must clear the variable to un-set it since setting it to undef will fail.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-5049983992806196415?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/5049983992806196415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=5049983992806196415' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/5049983992806196415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/5049983992806196415'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2009/05/moose-beginners-clear-predicate-and.html' title='Moose beginners: clear, predicate, and triggers'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-278812570354630458</id><published>2009-04-27T10:40:00.004-04:00</published><updated>2009-06-05T11:52:04.851-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FormHandler'/><title type='text'>Compound fields in forms</title><content type='html'>Many Perl form packages require nested forms of some sort for compound fields, but there are problems with that model. A form class--whether constructed from config settings in a file or declared in a Perl class--has lots of other attributes besides the fields. It made more sense to me to have a form with nested fields, where the fields can form a tree. That way attributes of the form do not have to be repeated in sub-forms. It also allows declaring subfields in the containing form, if that's what makes sense for this particular case.

Here's an example of how to do a form with a nested field in HTML::FormHandler:

&lt;pre&gt;
   package MyApp::Form;
   use HTML::FormHandler::Moose;
   extends 'HTML::FormHandler';

   has_field 'address' =&gt; ( type =&gt; 'Compound' );
   has_field 'address.street';
   has_field 'address.city';
   has_field 'address.zip' =&gt; ( type =&gt; '+Zip' );
   1;
&lt;/pre&gt;

The subfields are indicated by prefacing the field name with the name of the compound field and a dot. This form class will create a form with an 'address' field that contains an array of fields. 
&lt;br /&gt;
You can achieve the same thing by creating an 'Address' field:
&lt;pre&gt;
   package MyApp::Field::Address;
   use HTML::FormHandler::Moose;
   extends 'HTML::FormHandler::Field::Compound';

   has_field =&gt; 'street';
   has_field =&gt; 'city';
   has_field =&gt; 'zip' =&gt; ( type =&gt; '+Zip' );
   1;
&lt;/pre&gt;
(Where '+Zip' is a field class that you have written...) Then this field can be used in a form by simply doing:
&lt;pre&gt;
   has_field 'addresss' =&gt; ( type =&gt; '+Address' );
&lt;/pre&gt;
This feels simple and straightforward and, for me at least, matches my conceptual model of a form better than nested forms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-278812570354630458?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/278812570354630458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=278812570354630458' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/278812570354630458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/278812570354630458'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2009/04/compound-fields-in-forms.html' title='Compound fields in forms'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-2717184276352307539</id><published>2009-04-23T10:48:00.005-04:00</published><updated>2009-06-05T11:51:47.750-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FormHandler'/><title type='text'>HTML::FormHandler</title><content type='html'>When I started on a Catalyst project a year and a half ago I picked Form::Processor for form handling. I liked the architecture and I liked having the form in a Perl class so that I could do more-or-less anything that I wanted to with it. But then there was Moose, and I didn't want to have to switch back and forth between object systems. Plus you can do lots of shiny things with Moose. It's like a big Christmas present with lots of little parts that you can play with for ages... 
&lt;br /&gt;
&lt;br /&gt;
So I converted Form::Processor to Moose. But it was tough to maintain back compatibility and still use all that Moose-y goodness. In the end it seemed rational to start fresh with a new project: HTML::FormHandler. It has many excellent features, such as being able to define the fields declaratively, and there are plans for many more. Moose continues to be a pleasure to work with. It makes features easy that would have been horrendously difficult without it.

Of course, Reaction does wonderful things with Moose too, and is in many ways a more complete solution. But I think that HTML::FormHandler can still fill a niche. This is Perl after all--there has to be more than one way to do things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-2717184276352307539?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/2717184276352307539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=2717184276352307539' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/2717184276352307539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/2717184276352307539'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2009/04/htmlformhandler.html' title='HTML::FormHandler'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-6398405086009994311</id><published>2008-07-15T10:41:00.005-04:00</published><updated>2009-06-05T11:50:16.275-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='Moose'/><title type='text'>Moose is fun</title><content type='html'>I've been converting an old, badly designed set of Perl classes to Moose, and it's actually been &lt;i&gt;fun&lt;/i&gt;. I split the old classes up into a number of sub-objects, but was able to maintain the silly old interface with "handles", forwarding the calls to the appropriate class.
&lt;br /&gt;
&lt;br /&gt;
If you work with Perl and haven't tried Moose yet, you're missing something. The current three classes are 67 pages of printed Perl. I estimate that I'll end up with maybe 6 or 7 classes and probably no more than 20 pages.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-6398405086009994311?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/6398405086009994311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=6398405086009994311' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/6398405086009994311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/6398405086009994311'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2008/07/moose-is-fun.html' title='Moose is fun'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-8650100691713430792</id><published>2008-07-11T10:06:00.004-04:00</published><updated>2008-07-15T10:40:24.327-04:00</updated><title type='text'>Color schemes with vifm</title><content type='html'>This has been a "tools" day. I use vim for my IDE, but after 13 years of using still don't consider myself an expert. I've been using vimmate (in Ruby) for accessing the files and directories in my Catalyst project, but decided to find some option to recover the screen real estate. I ran across vifm, an ncurses vi-like file manager, which does pretty much what I want. However it comes with a dark background and I only do light backgrounds. The code has the ability to use a file of "colorschemes", but there is no documentation or example. I read the C code and figured out how to create a light background colorschemes file.

vifm uses a ~/.vifm directory for configuration. In that directory, create a "colorschemes" file (no extension). The goal with the colorschemes was apparently to have different colors for different types of directories, as you can see in the screen shot at &lt;a href="http://vifm.sourceforge.net/picture.html"&gt;http://vifm.sourceforge.net/picture.html&lt;/a&gt;,  but I just wanted a different default setup. In the "colorschemes" file I have the following:
&lt;pre&gt;
COLORSCHEME=Default
COLOR=MENU=4=7
COLOR=BORDER=7=0
COLOR=WIN=0=7
COLOR=STATUS_BAR=0=7
COLOR=CURR_LINE=7=4
COLOR=DIRECTORY=4=7
COLOR=LINK=4=7
COLOR=SOCKET=4=7
COLOR=DEVICE=1=7
COLOR=EXECUTABLE=2=7
COLOR=SELECTED=5=0
COLOR=CURRENT=7=0
&lt;/pre&gt;
This is not completely tested but seems to be working so far. If you want a different colorscheme for a different directory, you would add a line such as:

DIRECTORY=/Full/Path/To/Base/Directory

after the COLORSCHEME line. Comments start with #

G.Shank&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-8650100691713430792?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/8650100691713430792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=8650100691713430792' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/8650100691713430792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/8650100691713430792'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2008/07/color-schemes-with-vifm.html' title='Color schemes with vifm'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-1321661582754676037</id><published>2007-11-30T11:42:00.000-05:00</published><updated>2009-06-05T11:51:24.113-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Catalyst'/><title type='text'></title><content type='html'>&lt;h1&gt;Catalyst for Clueless Beginners&lt;/h1&gt;
&lt;p&gt;The &lt;a href="http://search.cpan.org/~jrockway/Catalyst-Manual-5.701003/lib/Catalyst/Manual/Tutorial.pod"&gt;Catalyst Tutorial&lt;/a&gt; is an excellent introduction to Catalyst, but can be hard for total beginners to get into. When I went through the "learning Catalyst" process I tried to make some notes and put together a verrrry simple step-by-step introduction for those of equal cluelessness. I've avoided using a database here because it adds a lot of complexity, and isn't necessary for "Hello, World".
&lt;/p&gt;
&lt;p&gt;
Note: the “$” at the beginning of shell commands is just to indicate a shell prompt. Do not type it.
&lt;/p&gt;
&lt;p&gt;
This tutorial assumes that you are running on a form of Linux. If you are running on Windows, you will have to translate the commands appropriately. The tutorial also assumes basic Perl knowledge. If you don't have that, you should get “Learning Perl” or some other tutorial and learn some Perl first.
&lt;/p&gt;
&lt;p&gt;
Catalyst is a &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;Model/View/Controller framework&lt;/a&gt;. You should at least know what that means before you start...
&lt;/p&gt;
&lt;h2&gt;Install and Start Catalyst&lt;/h2&gt;

&lt;p&gt;Create a Catalyst application:&lt;/p&gt;
&lt;pre&gt;
$ catalyst.pl MyApp
&lt;/pre&gt;
&lt;p&gt;
A long list of created directories and files should scroll up your screen.
&lt;/p&gt;
&lt;p&gt;
Change to the MyApp directory that was just created:
&lt;/p&gt;
&lt;pre&gt;$ cd MyApp&lt;/pre&gt;
&lt;p&gt;
Start up the server:
&lt;/p&gt;
&lt;pre&gt;$ script/myapp_server.pl&lt;/pre&gt;
&lt;p&gt;
Go to a browser and look at the url &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
It should display the Catalyst welcome page. If it doesn't, you probably have installation problems. You'll have to get things working before you can do anything else.
&lt;/p&gt;
&lt;p&gt;
Stop the server with a Ctrl-C.
&lt;/p&gt;
&lt;h2&gt;
Hello World!
&lt;/h2&gt;
&lt;p&gt;
Edit the lib/MyApp/Controller/Root.pm file. You will see the "default" subroutine, which is responsible for displaying the "welcome" screen that you just saw. Later on you'll want to change that to something more reasonable, such as a "404" message, but for now just leave it alone. Add the following subroutine:
&lt;/p&gt;
&lt;pre&gt;
sub hello : Global {
  my ( $self, $c) = @_;
  $c-&gt;response-&gt;body('Hello World!');
}
&lt;/pre&gt;
&lt;p&gt;
Notice the "Global term. This is a Catalyst "action" which will make this method one which executes directly after the site URL, or "localhost:3000/hello" at this point. “$c” is the Catalyst “context”, which is used to access Catalyst methods and variables. “response” refers to the Catalyst::Response class, which provides methods for responding to browser requests. “body” is the method which sets the output text to be sent to the browser. This command will send the string “Hello World!” to your browser.
&lt;/p&gt;
&lt;p&gt;
Save the file.
&lt;/p&gt;
&lt;p&gt;
Start the server, open a browser, and go to &lt;a href="http://localhost:3000/hello"&gt;http://localhost:3000/hello&lt;/a&gt; to see "Hello World!"
&lt;/p&gt;


&lt;h2&gt;Hello World using a View and a template&lt;/h2&gt;
&lt;p&gt;
In the Catalyst world, a "View" is not a page of XHTML or a template designed to present page to the browser. It is a Perl module which is more-or-less the equivalent of a config file for the template processor that you have chosen to use. Normally nothing much is in the lib/MyApp/View directory but a couple of Perl modules that set configuration options for Template Toolkit, or Mason, or whatever Perl module(s) you've chosen to handle your presentation (views).
&lt;/p&gt;
&lt;p&gt;
The actual templates are put someplace else, usually underneath the "root" directory. The default, if you do not actually set the directory in a config file, is in the root directory itself: MyApp/root. 
&lt;/p&gt;
&lt;p&gt;
The template files are not in the “View” directory, because the lib hierarchy is just for Perl modules. The perl module names are related to their place in the hierarchy.  For exammple, MyApp/View/TT.pm is the module MyApp::View::TT.
&lt;/p&gt;
&lt;p&gt; 
In order to create the TT config file, run:
&lt;/p&gt;
&lt;pre&gt;
$ script/myapp_create.pl view TT TT
&lt;/pre&gt;
&lt;p&gt;
This creates the lib/MyApp/View/TT.pm module, which is a subclass of Catalyst::View::TT
&lt;/p&gt;
&lt;p&gt; 
Now that the TT.pm "View" exists, Catalyst will automatically use it for displaying the view templates, using the "process" method that it inherits from the Catalyst::View::TT.pm class.
&lt;/p&gt;
&lt;p&gt;
Create a "hello.tt" template file, and put it in the "root" directory (MyApp/root):
&lt;/p&gt;
&lt;pre&gt;
[% META title = 'Hello World!' %]
&amp;#60;p&amp;#62;
  This is a TT view template, located in the root directory
&amp;#60;p&amp;#62;
&lt;/pre&gt;
&lt;p&gt;
Change the hello method to the following:
&lt;/p&gt;
&lt;pre&gt;
sub hello : Global 
{
  my ( $self, $c ) = @_;
  $c-&gt;stash-&gt;{template} = 'hello.tt';
}
&lt;/pre&gt;
&lt;p&gt;
The “stash” is a Perl hash where Catalyst stores variables that will be needed by other components, including templates. Here you are setting a hash element named “template” to “hello.tt”. The Catalyst “renderview” method will automatically take the file you set here, process it with  your View module (Template Toolkit), and send it to the browser.
&lt;/p&gt;
&lt;p&gt;
Start up the server and look at &lt;a href="http://localhost:3000/hello"&gt;http://localhost:3000/hello&lt;/a&gt;  again.
You should see a page saying "Hello World".
&lt;/p&gt;

&lt;h2&gt;Create a simple controller and an action&lt;/h2&gt;
&lt;p&gt;
Create a controller, "Site", for example:
&lt;/p&gt;
&lt;pre&gt;
$ script/myapp_create.pl controller Site
&lt;/pre&gt;
&lt;p&gt;
In the Site.pm file (in lib/MyApp/Controller) add the following method:
&lt;/p&gt;
&lt;pre&gt;
sub test : Local 
{
  my ( $self, $c ) = @_;
  $c-&gt;stash-&gt;{template} = 'site/test.tt';
}
&lt;/pre&gt;
&lt;p&gt;
Notice the "Local" on the method definition. This is necessary for the method to be executed using the "site/test" url. "Global" would put it in the root URL.
&lt;/p&gt;
&lt;p&gt;
Make a subdirectory, "site", in the directory for your template files ("root" by default, "root/src" if you use the TTSite layout), copy the hello.tt file into the site directory as test.tt:
&lt;/p&gt;
&lt;pre&gt;
$ cp hello.tt site/test.tt
&lt;/pre&gt;
&lt;p&gt;
Edit the test.tt file so you can recognize it...
&lt;/p&gt;
&lt;p&gt;
Bring up the server (or Ctrl-C to bring down and bring it up again), go to &lt;a href="http://localhost:3000/site/test"&gt;http://localhost:3000/site/test&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
You should see your test.tt file displayed.
&lt;/p&gt;


&lt;h2&gt;Using the TTSite Helper&lt;/h2&gt;

&lt;p&gt;
The TTSite helper will create some useful Template Toolkit templates, including header, footer, wrapper, and other files.
&lt;/p&gt;
&lt;p&gt;
If you want to try it, execute:
&lt;/p&gt;
&lt;pre&gt;
$ script/myapp_create.pl view TT TTSite
&lt;/pre&gt;
&lt;p&gt;
In addition to the TT.pm file created by "myapp_create.pl view TT TT", TTSite will also create a number of TT templates in the root/src and root/lib directories. It uses the ".tt2" extension, so if you prefer to use the more standard ".tt" extension, you will have to go through and rename the files, and modify the TT.pm file to use that extension.
&lt;/p&gt;
&lt;p&gt;
In addition, it creates a number of template files without extensions: header, footer, wrapper, etc. If you prefer to not have files without file type extensions, you'll have to rename them to header.tt, footer.tt, etc. This also requires changing the references to the files in the templates.
&lt;/p&gt;
&lt;p&gt;
You might want to try TTSite on a sample Catalyst app, examine the template files that it creates, and copy those that you find useful to your own app—unless you're doing a tutorial which counts on having the default TTSite installation. Template Toolkit is a powerful template system with lots of options and a template mini-language. It is well documented at &lt;a href="http://template-toolkit.org/"&gt;http://template-toolkit.org/&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;Where does Catalyst look for view templates?&lt;/h2&gt;
&lt;p&gt;
The default directory, if you haven't changed it is "root". If you want to use some other directory name, such as "public", you set the name in MyApp.pm.
&lt;/p&gt;
&lt;p&gt;
For example:
&lt;/p&gt;
&lt;pre&gt;
package MyApp::Controller::Test;
sub hello : Local { .. } 
&lt;/pre&gt;
&lt;p&gt;
Would by default look for a template in &lt;code&gt;&amp;#60;root&amp;#62;/test/hello&lt;/code&gt;. If you set TEMPLATE_EXTENSION in your TT.pm view module to '.tt', it will look for &lt;code&gt;&amp;#60;root&amp;#62;/test/hello.tt&lt;/code&gt;
&lt;p&gt;
If you are using TTSite defaults, then “included” templates will by in “MyApp/root/lib” and other templates will be in “MyApp/root/src”. It is possible to set both "src" and "include" directories to the same directory. When specifying templates in the stash or including templates in other templates (with the PROCESS, INCLUDE, and INSERT directives) you need to use subdirectories. 
&lt;/p&gt;
&lt;p&gt;For the example above that displays the site/test.tt template, you didn't have to specifically set the template file since it is the default location. You should be able to delete the line setting the template file and Catalyst will still find it, but there will be many times when you will want to specifically set the template to be displayed.

&lt;h2&gt;Catalyst Actions&lt;/h2&gt;
&lt;p&gt;
A Catalyst controller contains "actions", subroutines with special attributes, defined using Nicholas Clark's “Attributes” module. These action attributes provide information to the Catalyst dispatcher.
&lt;/p&gt;
&lt;p&gt;
Most URLs look something like:
&lt;/p&gt;
&lt;pre&gt;
http://somename.com/site/hello
&lt;/pre&gt;
&lt;p&gt;
In this URL, "site" is the controller, and "hello" is an action in the "site" controller.
&lt;/p&gt;
&lt;p&gt;
Actions which are called at the "root" level of the application go in the Root.pm module.
&lt;/p&gt;
&lt;p&gt;
You have seen three different action types: "Private" (on the default subroutine), "Global", and "Local".
&lt;/p&gt;
&lt;p&gt;
A "Global" action is mapped to the application base, with no controller name. A Global "hello" method would be executed with  http://somename.com/hello
&lt;/p&gt;
&lt;p&gt;
A "Local" action is executed by prefixing the controller name:
&lt;/p&gt;
&lt;pre&gt;
http://somename.com/test/hello
&lt;/pre&gt;
&lt;p&gt;
A "Private" action can't be executed directly by URL. It is usually executed by being called by some other action, except for the actions "default", "index", and "auto".
&lt;/p&gt;
&lt;p&gt;
There are a number of additional action types:
&lt;/p&gt;
&lt;pre&gt;
Literal Path:  sub bar : Path ('/foo/bar') { }
Regex:         sub bar : Regex ('^item(\d+)/order(\d+)$') { }
               This matches globally, without regard to the controller or namespace.
LocalRegex:    sub bar : LocalRegex('^widget(\d+)$') { }
               This matches only locally.
Chained:       sub bar : Chained : CaptureArgs(1) {} 
     or:       sub bar : Chained('catalog') : Args(1) {}
               See the documentation on DispatchType::Chained
Args:      action type Modifier.
   limits the number of path parts
&lt;/pre&gt;
&lt;p&gt;
To start with, most of your Controller actions will probably be "Local". Catalyst is very flexible in how you set up your actions and your URL structure, so you will have lots of choices about how to structure your application and your URLs.
&lt;/p&gt;
&lt;p&gt;
Using the &lt;a href="http://search.cpan.org/~mramberg/Catalyst-Runtime-5.7011/lib/Catalyst/DispatchType/Chained.pm"&gt;chained&lt;/a&gt; type of action can be particularly useful, but isn't advised for your first few Catalyst methods since it's a bit trickier.
&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;--------------------------------------------------------------------------&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;I hope this has been of some help to someone.&lt;p&gt;
&lt;p&gt;&lt;i&gt;G.Shank&lt;/i&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-1321661582754676037?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/1321661582754676037/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=1321661582754676037' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/1321661582754676037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/1321661582754676037'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2007/11/catalyst-for-clueless-beginners.html' title=''/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7103012096530045108.post-2573092205675529763</id><published>2007-11-13T11:18:00.000-05:00</published><updated>2009-06-05T11:51:31.606-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Catalyst'/><title type='text'>Learning Catalyst, a Perl framework</title><content type='html'>I'm learning Catalyst to use in a project, and find the documentation heavy going for a beginner. I started this blog to collect some of the information that I'm putting together.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7103012096530045108-2573092205675529763?l=catdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catdev.blogspot.com/feeds/2573092205675529763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7103012096530045108&amp;postID=2573092205675529763' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/2573092205675529763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7103012096530045108/posts/default/2573092205675529763'/><link rel='alternate' type='text/html' href='http://catdev.blogspot.com/2007/11/learning-catalyst-perl-framework.html' title='Learning Catalyst, a Perl framework'/><author><name>G.Shank</name><uri>http://www.blogger.com/profile/05698634171035921552</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>
