<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <title xmlns="http://www.w3.org/2005/Atom">Planet Catalyst</title>
  <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://planet.catalystframework.org/" type="text/html"/>
  <updated xmlns="http://www.w3.org/2005/Atom">2009-06-30T12:30:50-07:00</updated>
  <generator xmlns="http://www.w3.org/2005/Atom">Plagger/0.7.6</generator>
  <subtitle xmlns="http://www.w3.org/2005/Atom">Planet Catalyst</subtitle>
  <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:smartfeed:all</id>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Return to the Perl Survey</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://use.perl.org/~singingfish/journal/39187?from=rss" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">Back in January, I started doing work on the Perl Foundation grant for the perl survey. I'd gathered all the data together, and done a fairly sizable job of cleaning it up, when along came a new job and a horrendous set of deadlines for the now imminent Catalyst book.  Meanwhile I was waiting for Skud to give me the original Perl Survey 2007 report which had fallen off the net.

So for now, I'm going to go through the  survey report fairly slowly, replicating the previously presented analysis in R code and writing notes about what extra things can be done with the extant data.  Once this is done, I'll look at things that can be dropped from the old survey, and think about enhancing the next iteration of the survey with more questions.</summary>
    <content xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>Back in January, I started doing work on the Perl Foundation grant <a href="http://www.perlfoundation.org/kieren_diment_the_perl_survey">for the perl survey</a>. I'd gathered all the data together, and done a fairly sizable job of cleaning it up, when along came a new job and a horrendous set of deadlines for the now imminent <a href="http://www.apress.com/book/view/1430223650">Catalyst book</a>.  Meanwhile I was waiting for Skud to give me the original <a href="http://github.com/singingfish/perl-survey-2009/blob/3449fac299e2224e2ca7d78dd4f510aba5da7433/PerlSurvey2007A4.pdf">Perl Survey 2007 report</a> which had fallen off the net.

</p>
        <p>So for now, I'm going to go through the  survey report fairly slowly, <a href="http://github.com/singingfish/perl-survey-2009/blob/3449fac299e2224e2ca7d78dd4f510aba5da7433/R/01-gender.R">replicating</a> the previously presented analysis in <a href="http://www.r-project.org/">R</a> code and <a href="http://github.com/singingfish/perl-survey-2009/blob/3449fac299e2224e2ca7d78dd4f510aba5da7433/R/02-age.R">writing notes</a> about what extra things can be done with the extant data.  Once this is done, I'll look at things that can be dropped from the old survey, and think about enhancing the next iteration of the survey with more questions.</p>
      </div>
    </content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/"></dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-06-29T12:51:25Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-06-29T12:51:25Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">singingfish</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:http://use.perl.org/~singingfish/journal/39187?from=rss</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">InstantCRUD and FormHandler</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://perlalchemy.blogspot.com/2009/06/instantcrud-and-formhandler.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">The new version of Catalyst::Example::InstantCRUD is on CPAN.  This version uses FormHandler, is a bit nicer visually (I hope) and has a proof of concept experimental REST interface.</summary>
    <content xmlns="http://www.w3.org/2005/Atom" type="text">The new version of &lt;a href="http://search.cpan.org/~zby/Catalyst-Example-InstantCRUD/lib/Catalyst/Example/InstantCRUD.pm"&gt;Catalyst::Example::InstantCRUD&lt;/a&gt; is on CPAN.  This version uses FormHandler, is a bit nicer visually (I hope) and has a proof of concept experimental REST interface.&lt;div class="blogger-post-footer"&gt;&lt;img&gt;&lt;/div&gt;</content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/"></dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-06-29T07:36:00Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-06-29T07:36:00Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">zby</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:blogger.com,1999:blog-36345871.post-6144674523865162728</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Database Design Woes ( or "Something Wicked This Way Comes")</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://jjnapiorkowski.vox.com/library/post/database-design-woes-or-something-wicked-this-way-comes.html?_c=feed-atom" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">
            
                
         I wanted to drop in and explain my lengthy absence, especially given some interesting "part two" articles in my queue that several of you have emailed me hoping for an update.  In particular there's a pending summary of all the feedback regarding ...    
    Read and post comments   |   
    Send to a friend 


                
            
        </summary>
    <content xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
            
                <div xmlns="http://www.w3.org/1999/xhtml" xmlns:at="http://www.sixapart.com/ns/at">
         I wanted to drop in and explain my lengthy absence, especially given some interesting "part two" articles in my queue that several of you have emailed me hoping for an update.  In particular there's a pending summary of all the feedback regarding ...   <p> 
    <a href="http://jjnapiorkowski.vox.com/library/post/database-design-woes-or-something-wicked-this-way-comes.html?_c=feed-atom#comments">Read and post comments</a>   |   
    <a href="http://www.vox.com/share/6a00fa9675c31f000201101667fa11860c?_c=feed-atom">Send to a friend</a> 
</p>

                </div>
            
        </div>
    </content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">perl dbix-class dbic</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-06-26T13:19:10Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-06-26T13:19:10Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">John Napiorkowski</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:vox.com,2009-06-26:asset-6a00fa9675c31f000201101667fa11860c</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">CatalystX::Comments - RFC</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://perlalchemy.blogspot.com/2009/06/catalystxcomments-rfc.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">In Packaging cross cutting Catalyst features I promised to start developing a generic Catalyst comment sub-system.  Now I have incorporated the code samples into another experiment - ravlog(a blog engine by Gerda), and I would like to ask you what you think about it before releasing it to CPAN.Here is the current API - any comments are welcome. First you need to declare the controller using the new Moose style:package RavLog::Controller::View;use Moose;BEGIN {   extends 'Catalyst::Controller';   with 'CatalystX::Comments::ControllerFormRole';}has model_name =&gt; ( is =&gt; 'ro', isa =&gt; 'Str', default =&gt; 'DB' );The important part for us is of course with 'CatalystX::Comments::ControllerFormRole', the model_name attribute should hold the name of the model CatalystX::Comments will use to store the comments.After the declarations you can use CatalystX::Comments to put the comment form on the stash:sub view : Chained('base') PathPart('view') Args(0){   my ( $self, $c, $id ) = @_;...      $self-&gt;stash_comment_form( $c, $self-&gt;article-&gt;id );}That's the whole controller part - what it handles is generating the form for display and saving the submitted comments.  In the view templates you need to add: [% comment_form.render %]For displaying the comments themselves ravlog already had some template code and I did not change it.Next is the model part.  The library assumes that the DBIC model contains a Comment Result class like that one in ravlog.  Of course it does not need to have all of the columns, and can also have other columns - but these are the columns that will be filled by the CatalystX::Comments form.  Ideally that model part should be a Result base class - so that it can be subclassed and adapted to local circumstances (for example the belongs_to relationship to article needs to be changed), but for now I don't know how to do that.Now some more details. Thanks to html_prefix all parameters sent from this form are prefixed with the form name - so this form can be added to pages with other forms, it will recognize it's parameters.  The comments are saved only when the HTTP method used is POST, and after a successful comment creation the user is redirected to the same page (this seems a bit constraining - but see next paragraph - this is only meant to be temporary solution - I try to keep the API simple).Of course I understand that this can never cover the needs of a comment sub-system in a mature social web site.  I am thinking about it as more of scaffolding - code that let's you quickly develop a feature, see how it integrates with the rest of the user experience, formulate a more complete requirements list - and replace it part by part.</summary>
    <content xmlns="http://www.w3.org/2005/Atom" type="text">In &lt;a href="http://perlalchemy.blogspot.com/2009/06/packaging-cross-cutting-catalyst.html"&gt;Packaging cross cutting Catalyst features&lt;/a&gt; I promised to start developing a generic Catalyst comment sub-system.  Now I have incorporated the code samples into another experiment - &lt;a href="http://github.com/gshank/ravlog/tree/master"&gt;ravlog&lt;/a&gt;(a blog engine by Gerda), and I would like to ask you what you think about it before releasing it to CPAN.&lt;br /&gt;&lt;br /&gt;Here is the current API - any comments are welcome. First you need to declare the controller using the new Moose style:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;package RavLog::Controller::View;&lt;br /&gt;&lt;br /&gt;use Moose;&lt;br /&gt;BEGIN {&lt;br /&gt;   extends 'Catalyst::Controller';&lt;br /&gt;   with 'CatalystX::Comments::ControllerFormRole';&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;has model_name =&amp;gt; ( is =&amp;gt; 'ro', isa =&amp;gt; 'Str', default =&amp;gt; 'DB' );&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The important part for us is of course &lt;code&gt;with 'CatalystX::Comments::ControllerFormRole'&lt;/code&gt;, the &lt;code&gt;model_name&lt;/code&gt; attribute should hold the name of the model CatalystX::Comments will use to store the comments.&lt;br /&gt;After the declarations you can use CatalystX::Comments to put the comment form on the stash:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sub view : Chained('base') PathPart('view') Args(0)&lt;br /&gt;{&lt;br /&gt;   my ( $self, $c, $id ) = @_;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;   &lt;br /&gt;   $self-&amp;gt;stash_comment_form( $c, $self-&amp;gt;article-&amp;gt;id );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;That's the whole controller part - what it handles is generating the form for display and saving the submitted comments.  In the view templates you need to add: &lt;br /&gt;&lt;code&gt;&lt;br /&gt;[% comment_form.render %]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;For displaying the comments themselves ravlog already had some template code and I did not change it.&lt;br /&gt;&lt;br /&gt;Next is the model part.  The library assumes that the DBIC model contains a Comment Result class like &lt;a href="http://github.com/gshank/ravlog/blob/2c88dd45416b4ad15a7ec6ca7309d72aa6181279/lib/RavLog/Schema/DB/Comment.pm"&gt;that one in ravlog&lt;/a&gt;.  Of course it does not need to have all of the columns, and can also have other columns - but these are the columns that will be filled by the CatalystX::Comments form.  Ideally that model part should be a Result base class - so that it can be subclassed and adapted to local circumstances (for example the belongs_to relationship to article needs to be changed), but for now &lt;a href="http://lists.scsys.co.uk/pipermail/dbix-class/2009-June/007984.html"&gt;I don't know how to do that&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now some more details. Thanks to &lt;code&gt;html_prefix&lt;/code&gt; all parameters sent from this form are prefixed with the form name - so this form can be added to pages with other forms, it will recognize it's parameters.  The comments are saved only when the HTTP method used is POST, and after a successful comment creation the user is redirected to the same page (this seems a bit constraining - but see next paragraph - this is only meant to be temporary solution - I try to keep the API simple).&lt;br /&gt;&lt;br /&gt;Of course I understand that this can never cover the needs of a comment sub-system in a mature social web site.  I am thinking about it as more of &lt;a href="http://perlalchemy.blogspot.com/2009/06/on-scaffoldings.html"&gt;scaffolding&lt;/a&gt; - code that let's you quickly develop a feature, see how it integrates with the rest of the user experience, formulate a more complete requirements list - and replace it part by part.&lt;div class="blogger-post-footer"&gt;&lt;img&gt;&lt;/div&gt;</content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/"></dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-06-20T16:13:00Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-06-20T16:13:00Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">zby</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:blogger.com,1999:blog-36345871.post-7256027884746794795</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Users, Accounts, Identities and Roles</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://feedproxy.google.com/~r/yuvalkogman/~3/TFMBp3fgelM/users-accounts-identities-and-roles.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">In my previous post on modeling identity I showed how to decouple identities from accounts. Here is a more in depth look at how and when to separate all the pieces of a user's data from one another.

What is a user?

Applications typically have an object that models the user, but strictly speaking this is not really the user. The user is the human operating the user agent that interacts with the application.

The object approximating the human is a number of different things:




An identifier the human uses to authenticate
A collection of the user's data
An entity that acts on behalf of the user when interacting with the system


What's important to realize is that these things are actually separate parts of what the concept of a user means the system. Even if you roll all of them into a single class you should be able to make the distinction, and be able to break them out into separate objects should the need arise.

Whenever the representation of users in your database is too limiting, it's usually a direct consequence of the different aspects of the users' representation being lumped into a single user entity.

Refined concepts

Having a language with which to talk about a problem space is a vital tool for understanding and solving a problem. Here are some terms for this domain:


User The human using the application in meatspace
User agent The software through which the user interacts with the application
Identity A verifiable identifier for the user (e.g. a username)
Account Concrete data owned by the user (e.g. a user profile or user authored data)
Actor An entity with a goal in the system; something that performs operations on the data
Role A set of behaviors assumed by an actor


There is significant overlap in these terms:

For the duration of a session, user agent is synonymous with the user. Humans aren't made of software, so that's as close as the application will get. But this relationship is transient, the same user could use another user agent at a later point.

For the application to treat the user agent as if it were the user it must prove an identity. Typically the identity is a username and a shared secret is used for verification, demonstrating that the meat operating the user agent is who it claims to be.

The system stores any information about the user in the user's account data.

All actions in the system are carried out by an actor. In order to perform an action this actor assumes a role.

The tricky part is that the word "user" can be used to vaguely describe every one of these terms, usually without problems. However, when there is a need for a distinction this causes confusion.

So When does "user" break down? Whenever you need to have multiple instances of these entities, associated with a single human.

Roles

Roles solve the problem of needing separate access levels for different users.

A naive solution for multiple access levels involves an access level number (or even just a super user flag) that assigns additional privileges in the system, but it's very hard to change the access controls or to add finer grained permissions. If you assign each permission to each user separately this data quickly becomes unmaintainable as well.

Role based access control is a well understood solution to this problem. Permissions are assigned to roles, and roles, in turn, are assigned to users. I won't explain RBAC, it's far too broad a topic (Google is your friend). The point I'm trying to make is that this useful abstraction relies on decoupling the notion of who the user is from what the user is allowed to do.

Taking a page from capability based systems, instead of using roles as simple data you could even use them as the actual entry point to privileged operations. If the user doesn't have access to the role then sensitive operations are not blocked, they are simply inaccessible.

This is a compelling case for making roles a first class entity in the system. Most applications won't need such flexible authorization, but for the applications that do this is a powerful abstraction.

Suppose you have 3 roles: Guest, Unprivileged, and Administrator, these roles can be associated with very fine grained permissions. User agents representing unidentified users only have access to the Guest role, but logged in users can perform operations enabled by any other roles they've been granted.

If Administrator is needs to be split up into Moderator and Superuser, most of the code remains unchanged, and the operation that updates the existing user data is simple too, so making this change go live is relatively low risk.

Identities

Supporting multiple identities is another fairly well understood problem, at least recently. Many applications are starting to support OpenID authentication, and usually existing users expect to be able to associate their existing account with a new ID.

Another example is when Yahoo bought Flickr. Flickr suddenly had two keyspaces for identities, Yahoo IDs, and Flickr usernames, both of which mapped to a single account keyspace.

If you model identities as standalone data that references a user (as opposed to being a primary or surrogate key of the user) then you can easily integrate orthogonal authentication mechanisms like RPX, SSL certificates, or just simple usernames/passwords, without polluting any code except the authentication layer. The rest of the code can stay concerned with only the user account the IDs map to.

Actors

In this case I'm referring to actors in the UML sense, not the actor model sense.

I don't have a positive example for multiple actor support, but there are plenty of negative ones.

First and foremost is Google Apps. I've often wished I could access my work email/calendar from my personal account. Since my personal account will likely outlive my work account I don't want to use it for work or vice versa, but I still need to access the data from both. Fortunately for me email forwarding takes care of pretty much everything, but it's not a real solution.

Instead of being able to quickly switch contexts, I need to copy all the data into one place. Google knows I have access to my work email through forwarding so it lets me pretend I am sending email from there when I'm using my personal account, but there's still no segmentation.

Linode is another example. In order to manage work vs. non work machines I need to log out and log back in using a different account.

Hypothetically, the two actors that would act on my behalf in a these examples would be "Yuval the employee of Infinity Interactive" and "Yuval the unique snowflake". These are both extensions of my person, but they serve different purposes.

While an identity identifies the user from the outside, an actor identifies a user inside the system.

Accounts

In a simple system there usually isn't a strong case for multiple accounts, except when consolidating two accounts (a rare occurrence). Multiple accounts are usually an artifact of not supporting multiple actors.

However, if privacy or segmentation is a needed (suppose I would like to keep my personal data hidden from my colleagues) it becomes much more relevant. Unlike the other abstractions making this distinction is the responsibility of the user, not the application, so this is a niche feature.

Websites like MyOpenID or Plaxo support contextual profiles ("personas" in MyOpenID), allowing you to use separate data in separate contexts. This masquerading ability is an important feature in the services they provide due to the sensitivity of the data, but would be useful in many other sites, especially social networks.

Multiple accounts also facilitate shared accounts. A good example is twitter accounts for projects. These accounts don't represent a single human (usually the humans operating them have separate accounts), and the limitations are pretty painful:


The password is shared by all the collaborators
Another user agent must be used (or the user's personal session must be terminated) to operate the shared account


Lightweight context switching would solve this. A single identity could be used to authenticate the user to the application, and access all the accounts the user should have access to.

Accounts are closely related to actors. While accounts encapsulate the data belonging to user, actors define how a user interacts with other data.

Tying it all together

So here is my "mega ultimate" model for user data. This is contained in a single transient (session bound) user agent object, with multiple delegates.

These delegates are all broken out of the single user object. What remains of this object is a thin shell that unifies all of the delegates for a single user. This object represents the actual human, and all of the different objects they have access to.

The user object is static, it serves as the hub through which all other objects are associated. The user agent object is dynamic, it defines what is known about a user for the duration of a session.


The user agent object lives inside the session data.
Every "login" action creates an authentication token.
This authentication token marks an identity as verified in the user agent.
An identity is associated with the central user object.
A user object has access to multiple accounts.
Each account has any number of actors through which the user interacts with data outside of the account.
Each actor has of any number roles through which the it performs operations on that data.


The object representing the user agent needs to pick the appropriate delegate for each operation, and in most cases there is one obvious delegate to use.

Here is a diagram for the objects modeling an authenticated user:



The user agent object is responsible for picking the "active" instance of each of the multiple possible values.

In this case the user has a single user account. This account has access to two different data contexts through two actors, Work and Personal. There are only two roles in this system, Unprivileged which doesn't require authentication, and Known User which is just a default role for authenticated users. The user has registered both a username an OpenID.

The data in the dashed box has a lifetime of a single session, and represents the current set of behaviors the user is assuming, while the data on the right is persistent and represents anything the user can be.

The user signed in using the username, and is currently operating in the Work context. The Work actor's assigned roles are currently active.

Conversely, an unauthenticated user agent only has the guest role active, and makes no user data available:



A sign in action upgrades the guest user agent to an authenticated one by adding the auth token, which enables access to the full user data.

All activity that is made possible by the Unprivileged role is available to both unauthenticated and authenticated users, but actions that require a signed in user must be performed through the Known User role.

Here are some of the of the possibilities of this overengineering marvel:


Logging into the same account with different credentials.
Allowing an administrator to act as another user.
Accessing different data contexts (e.g. work vs. personal).
Shared accounts with proper segmentation of private data.
Fine grained privacy controls.
Fine grained, extensible permissions model.
Account consolidation process is obvious.
Stable internal identifiers.


These features aren't easy to implement with a single canonical user object whose ID is its primary key, and where all the data is stored as simple attributes of this objects.

YAGNI

Forget the "ultimate" model. It's overkill.

What's important is to merely understand the distinction between the different concepts. Most of the time you don't actually need to implement this distinction, a single user object will suffice.

Just make sure you know when and where to break things down into smaller bits, and don't do things that will prevent you from refactoring this in the future. When you need to implement one of those tricky features, avoid ad-hoc workarounds. In the long run, without having clear separation of concepts you're likely to end up with denormalized user data and inconsistent behavior.

Using duck typing (or roles or interfaces) you can simply treat your user object as an account/role/actor/identity object in the relevant parts of your code. As long as you keep the separation of the concepts clear in the usage, making the switch towards a separate first class object in the actual representation is a simple matter of refactoring.

The tradeoff of creating more abstraction layers provides, as always, flexibility at the cost of complexity. Often times we resort to inferior workarounds because they seem simpler, when in truth they are just dumbing down the problem. KISS is not a synonym for "half assed".

Catalyst

Apart from a few nits these concepts map pretty well Catalyst applications, using the existing authentication framework.

Using multiple distinct identities might require a bit of magic, as most user stores assume a user is an identity, instead of a user having multiple identity delegates.

By default you can still have multiple identities per user, but the user to identity relationship is-a, instead of has-a. The object that ends up in $c-&gt;user must also be the object negotiating the authentication sequence.

If you just treat each Catalyst level user object as an identity, and have the "real" user object become a delegate of that. The problem here is that of naming: $c-&gt;user-&gt;user can get pretty confusing when it really means $c-&gt;authenticated_identity-&gt;user.

Alternatively, the realm object can traverse the identity objects, and work with the "central" user object directly. In this approach $c-&gt;user is the user agent object.

A fully fledged user agent object would require custom work, as it must be tailored to your application's model of user data.

Secondly, the RBAC plugin provides a controller level predicate check for roles. The roles I've been describing in this post are more involved. Each user has role instances that are actual objects in the model. The model is manipulated by calling methods on these objects. The low level operations are still implemented by the corresponding model objects, but the controller actions invoked by the user don't access them directly, they are proxied by the roles.

Obviously the RBAC plugin can still check for the existence of these roles in order to generate simpler access violation errors earlier in the control flow, but it's no longer required to enforce the roles, enforcing is done using a safer capabilities inspired approach.

Finally, actors and accounts are purely application specific abstractions. If required, they are your responsibility to implement in the model, not the responsibility of a plugin or framework.

The End

I'd like to thank Chris Prather for his input and for inspiring this article in the first place by patientlty listening to my ranting as he was trying to rewrite the authentication subsystem of his IRC bots.</summary>
    <content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;In my previous post on &lt;a href="http://blog.woobling.org/2009/05/modeling-identity-with-kiokuxuser.html"&gt;modeling identity&lt;/a&gt; I showed how to decouple identities from accounts. Here is a more in depth look at how and when to separate &lt;em&gt;all&lt;/em&gt; the pieces of a user's data from one another.&lt;/p&gt;

&lt;h2&gt;What is a user?&lt;/h2&gt;

&lt;p&gt;Applications typically have an object that models the user, but strictly speaking this is not really the user. The user is the human operating the &lt;a href="http://en.wikipedia.org/wiki/User_agent"&gt;user agent&lt;/a&gt; that interacts with the application.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;object&lt;/em&gt; approximating the human is a number of different things:&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;An identifier the human uses to authenticate&lt;/li&gt;
&lt;li&gt;A collection of the user's data&lt;/li&gt;
&lt;li&gt;An entity that acts on behalf of the user when interacting with the system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What's important to realize is that these things are actually separate parts of what the concept of a user means the system. Even if you roll all of them into a single class you should be able to make the distinction, and be able to break them out into separate objects should the need arise.&lt;/p&gt;

&lt;p&gt;Whenever the representation of users in your database is too limiting, it's usually a direct consequence of the different aspects of the users' representation being lumped into a single user entity.&lt;/p&gt;

&lt;h2&gt;Refined concepts&lt;/h2&gt;

&lt;p&gt;Having a language with which to talk about a problem space is a vital tool for understanding and solving a problem. Here are some terms for this domain:&lt;/p&gt;

&lt;dl&gt;
&lt;dt&gt;&lt;strong&gt;User&lt;/strong&gt; &lt;dd&gt;The human using the application in meatspace&lt;/dd&gt;&lt;/dt&gt;
&lt;dt&gt;&lt;strong&gt;User agent&lt;/strong&gt; &lt;dd&gt;The software through which the user interacts with the application&lt;/dd&gt;&lt;/dt&gt;
&lt;dt&gt;&lt;strong&gt;Identity&lt;/strong&gt; &lt;dd&gt;A verifiable identifier for the user (e.g. a username)&lt;/dd&gt;&lt;/dt&gt;
&lt;dt&gt;&lt;strong&gt;Account&lt;/strong&gt; &lt;dd&gt;Concrete data owned by the user (e.g. a user profile or user authored data)&lt;/dd&gt;&lt;/dt&gt;
&lt;dt&gt;&lt;strong&gt;Actor&lt;/strong&gt; &lt;dd&gt;An entity with a goal in the system; something that performs operations on the data&lt;/dd&gt;&lt;/dt&gt;
&lt;dt&gt;&lt;strong&gt;Role&lt;/strong&gt; &lt;dd&gt;A set of behaviors assumed by an actor&lt;/dd&gt;&lt;/dt&gt;
&lt;/dl&gt;

&lt;p&gt;There is significant overlap in these terms:&lt;/p&gt;

&lt;p&gt;For the duration of a session, &lt;strong&gt;user agent&lt;/strong&gt; is synonymous with the &lt;strong&gt;user&lt;/strong&gt;. Humans aren't made of software, so that's as close as the application will get. But this relationship is transient, the same user could use another user agent at a later point.&lt;/p&gt;

&lt;p&gt;For the application to treat the user agent as if it were the user it must prove an &lt;strong&gt;identity&lt;/strong&gt;. Typically the identity is a username and a shared secret is used for verification, demonstrating that the meat operating the user agent is who it claims to be.&lt;/p&gt;

&lt;p&gt;The system stores any information about the user in the user's &lt;strong&gt;account&lt;/strong&gt; data.&lt;/p&gt;

&lt;p&gt;All actions in the system are carried out by an &lt;strong&gt;actor&lt;/strong&gt;. In order to perform an action this actor assumes a &lt;strong&gt;role&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The tricky part is that the word "user" can be used to vaguely describe every one of these terms, usually without problems. However, when there &lt;em&gt;is&lt;/em&gt; a need for a distinction this causes confusion.&lt;/p&gt;

&lt;p&gt;So When does "user" break down? Whenever you need to have multiple instances of these entities, associated with a single human.&lt;/p&gt;

&lt;h2&gt;Roles&lt;/h2&gt;

&lt;p&gt;Roles solve the problem of needing separate access levels for different users.&lt;/p&gt;

&lt;p&gt;A naive solution for multiple access levels involves an access level number (or even just a super user flag) that assigns additional privileges in the system, but it's very hard to change the access controls or to add finer grained permissions. If you assign each permission to each user separately this data quickly becomes unmaintainable as well.&lt;/p&gt;

&lt;p&gt;Role based access control is a well understood solution to this problem. Permissions are assigned to roles, and roles, in turn, are assigned to users. I won't explain RBAC, it's far too broad a topic (&lt;a href="http://www.google.com/search?q=role+based+access+control"&gt;Google is your friend&lt;/a&gt;). The point I'm trying to make is that this useful abstraction relies on decoupling the notion of who the user is from what the user is allowed to do.&lt;/p&gt;

&lt;p&gt;Taking a page from &lt;a href="http://en.wikipedia.org/wiki/Capability-based_security"&gt;capability based systems&lt;/a&gt;, instead of using roles as simple data you could even use them as the actual entry point to privileged operations. If the user doesn't have access to the role then sensitive operations are not blocked, they are simply inaccessible.&lt;/p&gt;

&lt;p&gt;This is a compelling case for making roles a first class entity in the system. Most applications won't need such flexible authorization, but for the applications that do this is a powerful abstraction.&lt;/p&gt;

&lt;p&gt;Suppose you have 3 roles: &lt;tt&gt;Guest&lt;/tt&gt;, &lt;tt&gt;Unprivileged&lt;/tt&gt;, and &lt;tt&gt;Administrator&lt;/tt&gt;, these roles can be associated with very fine grained permissions. User agents representing unidentified users only have access to the &lt;tt&gt;Guest&lt;/tt&gt; role, but logged in users can perform operations enabled by any other roles they've been granted.&lt;/p&gt;

&lt;p&gt;If &lt;tt&gt;Administrator&lt;/tt&gt; is needs to be split up into &lt;tt&gt;Moderator&lt;/tt&gt; and &lt;tt&gt;Superuser&lt;/tt&gt;, most of the code remains unchanged, and the operation that updates the existing user data is simple too, so making this change go live is relatively low risk.&lt;/p&gt;

&lt;h2&gt;Identities&lt;/h2&gt;

&lt;p&gt;Supporting multiple identities is another fairly well understood problem, at least recently. Many applications are starting to support &lt;a href="http://openid.net"&gt;OpenID&lt;/a&gt; authentication, and usually existing users expect to be able to associate their existing account with a new ID.&lt;/p&gt;

&lt;p&gt;Another example is when Yahoo bought Flickr. Flickr suddenly had two keyspaces for identities, Yahoo IDs, and Flickr usernames, both of which mapped to a single account keyspace.&lt;/p&gt;

&lt;p&gt;If you model identities as standalone data that &lt;em&gt;references&lt;/em&gt; a user (as opposed to being a primary or surrogate key of the user) then you can easily integrate orthogonal authentication mechanisms like &lt;a href="https://rpxnow.com/"&gt;RPX&lt;/a&gt;, SSL certificates, or just simple usernames/passwords, without polluting any code except the authentication layer. The rest of the code can stay concerned with only the user account the IDs map to.&lt;/p&gt;

&lt;h2&gt;Actors&lt;/h2&gt;

&lt;p&gt;In this case I'm referring to actors in the &lt;a href="http://en.wikipedia.org/wiki/Actor_(UML)"&gt;UML&lt;/a&gt; sense, not the &lt;a href="http://en.wikipedia.org/wiki/Actor_model"&gt;actor model&lt;/a&gt; sense.&lt;/p&gt;

&lt;p&gt;I don't have a positive example for multiple actor support, but there are plenty of negative ones.&lt;/p&gt;

&lt;p&gt;First and foremost is &lt;a href="https://www.google.com/a/"&gt;Google Apps&lt;/a&gt;. I've often wished I could access my work email/calendar from my personal account. Since my personal account will likely outlive my work account I don't want to use it for work or vice versa, but I still need to access the data from both. Fortunately for me email forwarding takes care of pretty much everything, but it's not a real solution.&lt;/p&gt;

&lt;p&gt;Instead of being able to quickly switch contexts, I need to copy all the data into one place. Google knows I have access to my work email through forwarding so it lets me pretend I am sending email from there when I'm using my personal account, but there's still no segmentation.&lt;/p&gt;

&lt;p&gt;Linode is another example. In order to manage work vs. non work machines I need to log out and log back in using a different account.&lt;/p&gt;

&lt;p&gt;Hypothetically, the two actors that would act on my behalf in a these examples would be "Yuval the employee of Infinity Interactive" and "Yuval the unique snowflake". These are both extensions of my person, but they serve different purposes.&lt;/p&gt;

&lt;p&gt;While an identity identifies the user from the outside, an actor identifies a user inside the system.&lt;/p&gt;

&lt;h2&gt;Accounts&lt;/h2&gt;

&lt;p&gt;In a simple system there usually isn't a strong case for multiple accounts, except when consolidating two accounts (a rare occurrence). Multiple accounts are usually an artifact of not supporting multiple actors.&lt;/p&gt;

&lt;p&gt;However, if privacy or segmentation is a needed (suppose I would like to keep my personal data hidden from my colleagues) it becomes much more relevant. Unlike the other abstractions making this distinction is the responsibility of the user, not the application, so this is a niche feature.&lt;/p&gt;

&lt;p&gt;Websites like &lt;a href="https://www.myopenid.com/"&gt;MyOpenID&lt;/a&gt; or &lt;a href="http://www.plaxo.com/"&gt;Plaxo&lt;/a&gt; support contextual profiles ("personas" in MyOpenID), allowing you to use separate data in separate contexts. This masquerading ability is an important feature in the services they provide due to the sensitivity of the data, but would be useful in many other sites, especially social networks.&lt;/p&gt;

&lt;p&gt;Multiple accounts also facilitate shared accounts. A good example is &lt;a href="http://twitter.com/"&gt;twitter&lt;/a&gt; accounts for projects. These accounts don't represent a single human (usually the humans operating them have separate accounts), and the limitations are pretty painful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The password is shared by all the collaborators&lt;/li&gt;
&lt;li&gt;Another user agent must be used (or the user's personal session must be terminated) to operate the shared account&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lightweight context switching would solve this. A single identity could be used to authenticate the user to the application, and access all the accounts the user should have access to.&lt;/p&gt;

&lt;p&gt;Accounts are closely related to actors. While accounts encapsulate the data belonging to user, actors define how a user interacts with other data.&lt;/p&gt;

&lt;h2&gt;Tying it all together&lt;/h2&gt;

&lt;p&gt;So here is my "mega ultimate" model for user data. This is contained in a single transient (session bound) user agent object, with multiple delegates.&lt;/p&gt;

&lt;p&gt;These delegates are all broken out of the single user object. What remains of this object is a thin shell that unifies all of the delegates for a single user. This object represents the actual human, and all of the different objects they have access to.&lt;/p&gt;

&lt;p&gt;The user object is static, it serves as the hub through which all other objects are associated. The user agent object is dynamic, it defines what is known about a user for the duration of a session.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The user agent object lives inside the session data.&lt;/li&gt;
&lt;li&gt;Every "login" action creates an authentication token.&lt;/li&gt;
&lt;li&gt;This authentication token marks an identity as verified in the user agent.&lt;/li&gt;
&lt;li&gt;An identity is associated with the central user object.&lt;/li&gt;
&lt;li&gt;A user object has access to multiple accounts.&lt;/li&gt;
&lt;li&gt;Each account has any number of actors through which the user interacts with data outside of the account.&lt;/li&gt;
&lt;li&gt;Each actor has of any number roles through which the it performs operations on that data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The object representing the user agent needs to pick the appropriate delegate for each operation, and in most cases there is one obvious delegate to use.&lt;/p&gt;

&lt;p&gt;Here is a diagram for the objects modeling an authenticated user:&lt;/p&gt;

&lt;img src="http://s3.amazonaws.com/nothingmuch/authenticated.png" alt="diagram representing an authenticated user agent"&gt;

&lt;p&gt;The user agent object is responsible for picking the "active" instance of each of the multiple possible values.&lt;/p&gt;

&lt;p&gt;In this case the user has a single user account. This account has access to two different data contexts through two actors, &lt;em&gt;Work&lt;/em&gt; and &lt;em&gt;Personal&lt;/em&gt;. There are only two roles in this system, &lt;em&gt;Unprivileged&lt;/em&gt; which doesn't require authentication, and &lt;em&gt;Known User&lt;/em&gt; which is just a default role for authenticated users. The user has registered both a username an OpenID.&lt;/p&gt;

&lt;p&gt;The data in the dashed box has a lifetime of a single session, and represents the current set of behaviors the user is assuming, while the data on the right is persistent and represents anything the user can be.&lt;/p&gt;

&lt;p&gt;The user signed in using the username, and is currently operating in the &lt;em&gt;Work&lt;/em&gt; context. The &lt;em&gt;Work&lt;/em&gt; actor's assigned roles are currently active.&lt;/p&gt;

&lt;p&gt;Conversely, an unauthenticated user agent only has the guest role active, and makes no user data available:&lt;/p&gt;

&lt;img src="http://s3.amazonaws.com/nothingmuch/guest.png" alt="diagram representing a guest user agent"&gt;

&lt;p&gt;A sign in action upgrades the guest user agent to an authenticated one by adding the auth token, which enables access to the full user data.&lt;/p&gt;

&lt;p&gt;All activity that is made possible by the &lt;em&gt;Unprivileged&lt;/em&gt; role is available to both unauthenticated and authenticated users, but actions that require a signed in user must be performed through the &lt;em&gt;Known User&lt;/em&gt; role.&lt;/p&gt;

&lt;p&gt;Here are some of the of the possibilities of this overengineering marvel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logging into the same account with different credentials.&lt;/li&gt;
&lt;li&gt;Allowing an administrator to act as another user.&lt;/li&gt;
&lt;li&gt;Accessing different data contexts (e.g. work vs. personal).&lt;/li&gt;
&lt;li&gt;Shared accounts with proper segmentation of private data.&lt;/li&gt;
&lt;li&gt;Fine grained privacy controls.&lt;/li&gt;
&lt;li&gt;Fine grained, extensible permissions model.&lt;/li&gt;
&lt;li&gt;Account consolidation process is obvious.&lt;/li&gt;
&lt;li&gt;Stable internal identifiers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These features aren't easy to implement with a single canonical user object whose ID is its primary key, and where all the data is stored as simple attributes of this objects.&lt;/p&gt;

&lt;h2&gt;YAGNI&lt;/h2&gt;

&lt;p&gt;Forget the "ultimate" model. It's &lt;a href="http://en.wikipedia.org/wiki/YAGNI"&gt;overkill&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What's important is to merely &lt;em&gt;understand&lt;/em&gt; the distinction between the different concepts. Most of the time you don't actually need to implement this distinction, a single user object will suffice.&lt;/p&gt;

&lt;p&gt;Just make sure you know when and where to break things down into smaller bits, and don't do things that will prevent you from refactoring this in the future. When you need to implement one of those tricky features, avoid ad-hoc workarounds. In the long run, without having clear separation of concepts you're likely to end up with denormalized user data and inconsistent behavior.&lt;/p&gt;

&lt;p&gt;Using &lt;a href="http://en.wikipedia.org/wiki/Duck_typing"&gt;duck typing&lt;/a&gt; (or &lt;a href="http://search.cpan.org/perldoc?Moose::Role"&gt;roles&lt;/a&gt; or interfaces) you can simply treat your user object as an account/role/actor/identity object in the relevant parts of your code. As long as you keep the separation of the concepts clear in the usage, making the switch towards a separate first class object in the actual representation is a simple matter of refactoring.&lt;/p&gt;

&lt;p&gt;The tradeoff of creating more abstraction layers provides, as always, flexibility at the cost of complexity. Often times we resort to inferior workarounds because they seem simpler, when in truth they are just dumbing down the problem. &lt;a href="http://en.wikipedia.org/wiki/KISS_principle"&gt;KISS&lt;/a&gt; is not a synonym for "half assed".&lt;/p&gt;

&lt;h2&gt;Catalyst&lt;/h2&gt;

&lt;p&gt;Apart from a few nits these concepts map pretty well &lt;a href="http://www.catalystframework.org/"&gt;Catalyst&lt;/a&gt; applications, using the existing &lt;a href="http://search.cpan.org/dist/Catalyst-Plugin-Authentication/"&gt;authentication framework&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Using multiple distinct identities might require a bit of magic, as most user stores assume a user is an identity, instead of a user having multiple identity delegates.&lt;/p&gt;

&lt;p&gt;By default you can still have multiple identities per user, but the user to identity relationship is-a, instead of has-a. The object that ends up in &lt;tt&gt;$c-&amp;gt;user&lt;/tt&gt; must also be the object negotiating the authentication sequence.&lt;/p&gt;

&lt;p&gt;If you just treat each Catalyst level user object as an identity, and have the "real" user object become a delegate of that. The problem here is that of naming: &lt;tt&gt;$c-&amp;gt;user-&amp;gt;user&lt;/tt&gt; can get pretty confusing when it really means &lt;tt&gt;$c-&amp;gt;authenticated_identity-&amp;gt;user&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Alternatively, the &lt;a href="http://search.cpan.org/perldoc?Catalyst::Authentication::Realm"&gt;realm&lt;/a&gt; object can traverse the identity objects, and work with the "central" user object directly. In this approach &lt;tt&gt;$c-&amp;gt;user&lt;/tt&gt; is the user agent object.&lt;/p&gt;

&lt;p&gt;A fully fledged user agent object would require custom work, as it must be tailored to your application's model of user data.&lt;/p&gt;

&lt;p&gt;Secondly, the &lt;a href="http://search.cpan.org/perldoc?Catalyst::Plugin::Authorization::Roles"&gt;RBAC plugin&lt;/a&gt; provides a controller level predicate check for roles. The roles I've been describing in this post are more involved. Each user has role instances that are actual objects in the model. The model is manipulated by calling methods on these objects. The low level operations are still implemented by the corresponding model objects, but the controller actions invoked by the user don't access them directly, they are proxied by the roles.&lt;/p&gt;

&lt;p&gt;Obviously the RBAC plugin can still check for the existence of these roles in order to generate simpler access violation errors earlier in the control flow, but it's no longer required to enforce the roles, enforcing is done using a safer capabilities inspired approach.&lt;/p&gt;

&lt;p&gt;Finally, actors and accounts are purely application specific abstractions. If required, they are your responsibility to implement in the model, not the responsibility of a plugin or framework.&lt;/p&gt;

&lt;h2&gt;The End&lt;/h2&gt;

&lt;p&gt;I'd like to thank &lt;a href="http://chris.prather.org/"&gt;Chris Prather&lt;/a&gt; for his input and for inspiring this article in the first place by patientlty listening to my ranting as he was trying to &lt;a href="http://github.com/perigrin/flexo-bot/tree/master"&gt;rewrite&lt;/a&gt; the authentication subsystem of his &lt;a href="http://chris.prather.org/perl/stupid-bot-tricks-part-i/"&gt;IRC bots&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/TFMBp3fgelM"&gt;</content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">openid catalyst identity authentication perl</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-06-16T11:33:00Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-06-16T11:33:00Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">nothingmuch</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:blogger.com,1999:blog-876358347971598886.post-8704853250981545082</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Form rendering and CSS</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://perlalchemy.blogspot.com/2009/06/form-rendering-and-css.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">I tried a few times to learn CSS, but not really seriously, I guess, since I still know only the most basic things.  So I am a bit lost now when I need a nice and universal CSS for FormHandler forms in Catalyst::Example::InstantCRUD.  Or perhaps I should say HTML::FormHandler::Render::Simple forms instead of just FormHandler forms as theoretically the HTML rendering part is separated from the main FormHandler code, so that if this Simple renderer turns out really too simplistic I can also write a HTML::FormHandler::Render::NotSoSimple to get the right HTML.I started reviewing the options and it seems that there are three general approaches to having aligned forms:tablesdivslistsno additional markupPlus some appriopriate CSS. I think the 'no additional markup' option could never accommodate for error messages, so I leave this one out.  This leaves me with three options.  I am sure that not everything can be done in each one - but I think we can add a 'style' parameter to the renderer to make it configurable.Next thing is the recently popular CSS grids - anyone using them?  They seem like a nice option for someone needing some universal defaults and the SenCSS example even contains a form styled in two ways (vertical and horizontal alignments) - but would it work with error messages?  And the Blueprint one even shows a div with the error class - but how that is to be inserted into the form?  I guess each one requires it's own way of HTML structuring.</summary>
    <content xmlns="http://www.w3.org/2005/Atom" type="text">I tried a few times to learn CSS, but not really seriously, I guess, since I still know only the most basic things.  So I am a bit lost now when I need a nice and universal CSS for FormHandler forms in Catalyst::Example::InstantCRUD.  Or perhaps I should say HTML::FormHandler::Render::Simple forms instead of just FormHandler forms as theoretically the HTML rendering part is separated from the main FormHandler code, so that if this Simple renderer turns out really too simplistic I can also write a HTML::FormHandler::Render::NotSoSimple to get the right HTML.&lt;br /&gt;&lt;br /&gt;I started reviewing the options and it seems that there are three general approaches to having aligned forms:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;tables&lt;br /&gt;&lt;li&gt;divs&lt;br /&gt;&lt;li&gt;lists&lt;br /&gt;&lt;li&gt;no additional markup&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Plus some appriopriate CSS. I think the 'no additional markup' option could never accommodate for error messages, so I leave this one out.  This leaves me with three options.  I am sure that not everything can be done in each one - but I think we can add a 'style' parameter to the renderer to make it configurable.&lt;br /&gt;&lt;br /&gt;Next thing is the recently popular CSS grids - anyone using them?  They seem like a nice option for someone needing some universal defaults and &lt;a href="http://sencss.kilianvalkhof.com/example.html"&gt;the SenCSS example&lt;/a&gt; even contains a form styled in two ways (vertical and horizontal alignments) - but would it work with error messages?  &lt;a href="http://blueprintcss.org/tests/parts/forms.html#"&gt;And the Blueprint one&lt;/a&gt; even shows a div with the error class - but how that is to be inserted into the form?  I guess each one requires it's own way of HTML structuring.&lt;div class="blogger-post-footer"&gt;&lt;img&gt;&lt;/div&gt;</content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/"></dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-06-07T19:09:00Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-06-07T19:09:00Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">zby</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:blogger.com,1999:blog-36345871.post-504481070130639158</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Packaging cross cutting Catalyst features</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://perlalchemy.blogspot.com/2009/06/packaging-cross-cutting-catalyst.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">A recurring subject on the Catalyst mailing list is about packaging functionality that is not entirely comprised in one of the Model View or Controller parts of the framework (and is not a full application on itself).  This is hard and still there aren't many CPAN libraries that do that. One solution to that is writing "helpers" that generate the integration code into your application files.  As with all code generation this solution creates many new problems - and ideally we would like to avoid it.  To try out what can be done about that I decided to write a generic comment system for Catalyst (+DBIC, TT and FormHandler).  I've already posted the the first code samples to the Catalyzed wiki.  The form code and the controller stuff seems closed - it does not need to refer to things from outside but in the DBIC declarations the belongs_to relation of the comments needs to relate to an external table and it's primary key (I assume that comments belong to an article/post/something).  How that can be made configurable?</summary>
    <content xmlns="http://www.w3.org/2005/Atom" type="text">A &lt;a href="http://lists.scsys.co.uk/pipermail/catalyst-dev/2009-June/001676.html"&gt;recurring subject on the Catalyst mailing list&lt;/a&gt; is about packaging functionality that is not entirely comprised in one of the Model View or Controller parts of the framework (and is not a full application on itself).  This is hard and still there aren't many CPAN libraries that do that. One solution to that is writing "helpers" that generate the integration code into your application files.  As with all code generation this solution creates many new problems - and ideally we would like to avoid it.  &lt;br /&gt;&lt;p&gt;&lt;br /&gt;To try out what can be done about that I decided to write a generic comment system for Catalyst (+DBIC, TT and FormHandler).  I've already posted the &lt;a href="http://wiki.catalyzed.org/codesamples/zby"&gt;the first code samples&lt;/a&gt; to the Catalyzed wiki.  The form code and the controller stuff seems closed - it does not need to refer to things from outside but in the DBIC declarations the belongs_to relation of the comments needs to relate to an external table and it's primary key (I assume that comments belong to an article/post/something).  How that can be made configurable?&lt;div class="blogger-post-footer"&gt;&lt;img&gt;&lt;/div&gt;</content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/"></dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-06-05T17:00:00Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-06-05T17:00:00Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">zby</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:blogger.com,1999:blog-36345871.post-4352649909878218886</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">RFC: Non Code Data Directories and Standards for Catalyst</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://jjnapiorkowski.vox.com/library/post/rfc-non-code-data-directories-and-standards-for-catalyst.html?_c=feed-atom" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">
            
                
         Introduction  This blog is a proposal and request for comments regarding adopting the XDG Filesystem Hierarchy as a option for managing all the non code data composing a Catalyst application.  The Problem  Right now when you create a new Catalyst ...    
    Read and post comments   |   
    Send to a friend 


                
            
        </summary>
    <content xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
            
                <div xmlns="http://www.w3.org/1999/xhtml" xmlns:at="http://www.sixapart.com/ns/at">
         Introduction  This blog is a proposal and request for comments regarding adopting the XDG Filesystem Hierarchy as a option for managing all the non code data composing a Catalyst application.  The Problem  Right now when you create a new Catalyst ...   <p> 
    <a href="http://jjnapiorkowski.vox.com/library/post/rfc-non-code-data-directories-and-standards-for-catalyst.html?_c=feed-atom#comments">Read and post comments</a>   |   
    <a href="http://www.vox.com/share/6a00fa9675c31f0002011016900b70860d?_c=feed-atom">Send to a friend</a> 
</p>

                </div>
            
        </div>
    </content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">perl rfc catalyst xdg</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-06-03T16:47:48Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-06-03T16:47:48Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">John Napiorkowski</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:vox.com,2009-06-03:asset-6a00fa9675c31f0002011016900b70860d</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Become a Hero Plumber</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://feedproxy.google.com/~r/yuvalkogman/~3/jaKZ0P5g0e4/become-hero-plumber.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">Perl's reference counting memory management has some advantages, but it's easy to get cycle management subtly wrong, causing memory and resource leaks that are often hard to find.

If you know you've got a leak and you've narrowed it down then Devel::Cycle can be used to make sense out of things, and Test::Memory::Cycle makes it very easy to integrate this into unit tests.

Harder to find leaks are usually the result of combining large components together. Reading through thousands of lines of dumps is pretty impractical; even eating colored mushrooms isn't going to help you much.

For instance, this is a classic way to accidentally leak the context object in Catalyst:


sub action : Local {
    my ( $self, $c ) = @_;

    my $object = $c-&gt;model("Thingies")-&gt;blah;

    $c-&gt;stash-&gt;{foo} = sub {
        $object-&gt;foo($c);
    };

    $c-&gt;forward("elsewhere");
}

That action will leak all the transient data created or loaded in every request. The cyclical structure is caused by $c being captured in a closure, that is indirectly referred to by $c itself. The fix is to call weaken($c) in the body of the action.

This example is pretty obvious, but if the model was arguably cleaner and used ACCEPT_CONTEXT to parameterize on $c, the leak would be harder to spot.

In order to find these trickier leaks there are a few modules on the CPAN that can be very helpful, if you know how and when to use them effectively.

The first of these is Devel::Leak. The basic principle is very simple: it makes note of all the live SVs at a given point in your problem, you let some code run, and then when that code has finished you can ensure that the count is still the same.

Devel::Leak is handy because it's fairly predictable and easy to use, so you can narrow down the source of the leak using a binary search quite easily. Unfortunately you can only narrow things down so far, especially if callbacks are involved. For instance the Catalyst example above would be hard to analyze since the data is probably required by the views. The smallest scope we can test is probably a single request.

Devel::Gladiator can be used to write your own more detailed Devel::Leak workalike. It lets you enumerate all the live values at a given point in time. Just be aware that the data structures you use to track leaks will also be reported.

Using Devel::Gladiator you can also find a list of suspicious objects and then analyze them with Devel::Cycle quite easily.

Sometimes the data that is leaking is not the data responsible for the leak. If you need to find the structures which are pointing to a leaked value then Devel::FindRef can be very helpful. The hardest challenge is picking the right value to track, so that you can get a small enough report that you can make sense of it.

Devel::Refcount and Devel::Peek can be used to check the reference count of values, but remember take into account all the references to a given value that are also in the stack. Just because the ref count is 2 for a value that's supposed to be referred to once does not mean that it's the root of a cyclical structure.

A more managed approach is using instance tracking in your leaked classes, ensuring that construction and destruction are balanced on the dynamic scope. You can do this manually for more accurate results, or you can use something like Devel::Events::Objects. I personally dislike Devel::Leak::Object because you have no control over the scope of the leak checking, but if you're writing a script then it might work for you.

Lastly, if you suspect you've found a leak then Data::Structure::Util is a rather blunt way of confirming that suspicion.</summary>
    <content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;Perl's &lt;a href="http://www.memorymanagement.org/glossary/r.html#reference.counting"&gt;reference counting&lt;/a&gt; memory management has some &lt;a href="http://en.wikipedia.org/wiki/RAII"&gt;advantages&lt;/a&gt;, but it's easy to get cycle &lt;a href="http://search.cpan.org/dist/Scalar-List-Utils/lib/Scalar/Util.pm#weaken"&gt;management&lt;/a&gt; subtly wrong, causing memory and resource leaks that are often hard to find.&lt;/p&gt;

&lt;p&gt;If you know you've got a leak and you've narrowed it down then &lt;a href="http://search.cpan.org/perldoc?Devel::Cycle"&gt;&lt;tt&gt;Devel::Cycle&lt;/tt&gt;&lt;/a&gt; can be used to make sense out of things, and &lt;a href="http://search.cpan.org/perldoc?Test::Memory::Cycle"&gt;&lt;tt&gt;Test::Memory::Cycle&lt;/tt&gt;&lt;/a&gt; makes it very easy to integrate this into unit tests.&lt;/p&gt;

&lt;p&gt;Harder to find leaks are usually the result of combining large components together. Reading through thousands of lines of dumps is pretty impractical; even eating colored mushrooms isn't going to help you much.&lt;/p&gt;

&lt;p&gt;For instance, this is a classic way to accidentally leak the context object in &lt;a href="http://www.catalystframework.org/"&gt;Catalyst&lt;/a&gt;:&lt;/p&gt;

&lt;pre id="fake-gist-117408" class="fake-gist"&gt;
sub action : Local {
    my ( $self, $c ) = @_;

    my $object = $c-&amp;gt;model(&amp;quot;Thingies&amp;quot;)-&amp;gt;blah;

    $c-&amp;gt;stash-&amp;gt;{foo} = sub {
        $object-&amp;gt;foo($c);
    };

    $c-&amp;gt;forward(&amp;quot;elsewhere&amp;quot;);
}&lt;/pre&gt;

&lt;p&gt;That action will leak all the transient data created or loaded in every request. The cyclical structure is caused by &lt;tt&gt;$c&lt;/tt&gt; being captured in a closure, that is indirectly referred to by &lt;tt&gt;$c&lt;/tt&gt; itself. The fix is to call &lt;tt&gt;weaken($c)&lt;/tt&gt; in the body of the action.&lt;/p&gt;

&lt;p&gt;This example is pretty obvious, but if the model was arguably cleaner and used &lt;tt&gt;ACCEPT_CONTEXT&lt;/tt&gt; to parameterize on &lt;tt&gt;$c&lt;/tt&gt;, the leak would be harder to spot.&lt;/tt&gt;

&lt;p&gt;In order to find these trickier leaks there are a few modules on the CPAN that can be very helpful, if you know how and when to use them effectively.&lt;/p&gt;

&lt;p&gt;The first of these is &lt;a href="http://search.cpan.org/perldoc?Devel::Leak"&gt;&lt;tt&gt;Devel::Leak&lt;/tt&gt;&lt;/a&gt;. The basic principle is very simple: it makes note of all the live SVs at a given point in your problem, you let some code run, and then when that code has finished you can ensure that the count is still the same.&lt;/p&gt;

&lt;p&gt;&lt;tt&gt;Devel::Leak&lt;/tt&gt; is handy because it's fairly predictable and easy to use, so you can narrow down the source of the leak using a binary search quite easily. Unfortunately you can only narrow things down so far, especially if callbacks are involved. For instance the Catalyst example above would be hard to analyze since the data is probably required by the views. The smallest scope we can test is probably a single request.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://search.cpan.org/perldoc?Devel::Gladiator"&gt;&lt;tt&gt;Devel::Gladiator&lt;/tt&gt;&lt;/a&gt; can be used to write your own more detailed &lt;tt&gt;Devel::Leak&lt;/tt&gt; workalike. It lets you enumerate all the live values at a given point in time. Just be aware that the data structures you use to track leaks will also be reported.&lt;/p&gt;

&lt;p&gt;Using &lt;tt&gt;Devel::Gladiator&lt;/tt&gt; you can also find a list of suspicious objects and then analyze them with &lt;tt&gt;Devel::Cycle&lt;/tt&gt; quite easily.&lt;/p&gt;

&lt;p&gt;Sometimes the data that is leaking is not the data responsible for the leak. If you need to find the structures which are pointing to a leaked value then &lt;a href="http://search.cpan.org/perldoc?Devel::FindRef"&gt;&lt;tt&gt;Devel::FindRef&lt;/tt&gt;&lt;/a&gt; can be very helpful. The hardest challenge is picking the right value to track, so that you can get a small enough report that you can make sense of it.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://search.cpan.org/perldoc?Devel::Refcount"&gt;&lt;tt&gt;Devel::Refcount&lt;/tt&gt;&lt;/a&gt; and &lt;a href="http://search.cpan.org/perldoc?Devel::Peek"&gt;&lt;tt&gt;Devel::Peek&lt;/tt&gt;&lt;/a&gt; can be used to check the reference count of values, but remember take into account all the references to a given value that are also in the stack. Just because the ref count is 2 for a value that's supposed to be referred to once does not mean that it's the root of a cyclical structure.&lt;/p&gt;

&lt;p&gt;A more managed approach is using instance tracking in your leaked classes, ensuring that construction and destruction are balanced on the dynamic scope. You can do this manually for more accurate results, or you can use something like &lt;a href="http://search.cpan.org/perldoc?Devel::Events::Objects"&gt;Devel::Events::Objects&lt;/a&gt;. I personally dislike &lt;a href="http://search.cpan.org/perldoc?Devel::Leak::Object"&gt;&lt;tt&gt;Devel::Leak::Object&lt;/tt&gt;&lt;/a&gt; because you have no control over the scope of the leak checking, but if you're writing a script then it might work for you.&lt;/p&gt;

&lt;p&gt;Lastly, if you suspect you've found a leak then &lt;a href="http://search.cpan.org/dist/Data-Structure-Util/lib/Data/Structure/Util.pm#circular_off"&gt;&lt;tt&gt;Data::Structure::Util&lt;/tt&gt;&lt;/a&gt; is a rather blunt way of confirming that suspicion.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/jaKZ0P5g0e4"&gt;</content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">catalyst perl memory leak</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-05-25T05:58:00Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-05-25T05:58:00Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">nothingmuch</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:blogger.com,1999:blog-876358347971598886.post-7663345898604403078</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Under the palm tree (are-we-going-to-need-it.html)</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://desert-island.me.uk/~castaway/blog/are-we-going-to-need-it.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">Are we going to need it?

Odd flash of inspiration while washing up (yay for mindless activity)
and also listening to a TED talk.

I often grumble at Moose. Though not actually at Moose itself, just at
seemingly everyone and everything jumping on the bandwagon. I also
want to use Reaction, cos Matt wrote/writes it, and from the outside
it feels like a great idea.

But part of me doesn't think so. I think I know why now. Maybe I've
been reading too many articles on Agile and so on. Specifically the
principles of DoTheSimplestThingThatCouldPossiblyWork, and
YouAintGonnaNeedIt.

Reaction is a complex piece
of software, built on top of two other pieces of complex software,
Catalyst, and
Moose. That's a whole stack of
code. As people jokingly say "It installs half of CPAN". Don't get me
wrong, software re-use is good and if I actually needed a piece of
software that does all the many things that these three do, I'd use
them.

But I don't. Applications (and websites) don't often start complex,
they gather complexity over time.

For one or two web pages, maybe even ten, I can write them by hand. Ok
so I probably copy the header and footer after a few. When I come to
write the eleventh one, this becomes tedious. So instead I could use
something like Template Toolkit's ttree, to produce a bunch of pages
out of some templates. At some point I find myself needing something
dynamic, or the concept of users, then I may go fetch Catalyst.

And that's as far as I've got. Which step makes me need Reaction? The
one where 90% of my website is interactive? I've not written too many
of those, but the few I have, Catalyst has sufficed.

You're probably thinking now, that I just don't write the same kind of
applications/websites as others do. Thats possibly true.

But again, Agile ways of doing things suggest we write the minimal
amount of code we can get away with, to imlement the currently
required features. That we don't plan ahead and add more code for
potential features later, they will be re-thought anyway. That we
release early, and often, and gather feedback for improvement, and
then add new features.

Not forgetting to refactor. To upgrade, to replace the entire
framework if needed.

To be practical

I think, what I'm looking for is, a guide for newcomers to explain and
help ths progression. How to upgrade your site or code, from a few
pages, to some dynamic bits, to a full blown interactive site. Or even
not, not every site wants or needs to go that far. Not all code needs
to be able to use email.

There seem to exist many articles on how to write this complex code,
but not enough that explain how to come to the conclusion that you
need it.

Maybe this is also why there are still many many more people writing
about how to do CGI scripts in Perl, than how to use Moose. The
transition is missing.

(With thanks to Elizabeth Gilbert on nurturing creativity)

Right, now I'm off to move the fledgling DBIx::Class website from some
hand written pages to ttree.

@public,programming,perl,thinking
</summary>
    <content xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><h1>Are we going to need it?</h1>

<p>Odd flash of inspiration while washing up (yay for mindless activity)
and also listening to a TED talk.</p>

<p>I often grumble at Moose. Though not actually at Moose itself, just at
seemingly everyone and everything jumping on the bandwagon. I also
want to use Reaction, cos Matt wrote/writes it, and from the outside
it feels like a great idea.</p>

<p>But part of me doesn't think so. I think I know why now. Maybe I've
been reading too many articles on Agile and so on. Specifically the
principles of DoTheSimplestThingThatCouldPossiblyWork, and
YouAintGonnaNeedIt.</p>

<p><a href="http://code2.0beta.co.uk/reaction/svn">Reaction</a> is a complex piece
of software, built on top of two other pieces of complex software,
<a href="http://search.cpan.org/dist/Catayst-Runtime">Catalyst</a>, and
<a href="http://search.cpan.org/dist/Moose">Moose</a>. That's a whole stack of
code. As people jokingly say "It installs half of CPAN". Don't get me
wrong, software re-use is good and if I actually needed a piece of
software that does all the many things that these three do, I'd use
them.</p>

<p>But I don't. Applications (and websites) don't often start complex,
they gather complexity over time.</p>

<p>For one or two web pages, maybe even ten, I can write them by hand. Ok
so I probably copy the header and footer after a few. When I come to
write the eleventh one, this becomes tedious. So instead I could use
something like Template Toolkit's ttree, to produce a bunch of pages
out of some templates. At some point I find myself needing something
dynamic, or the concept of users, then I may go fetch Catalyst.</p>

<p>And that's as far as I've got. Which step makes me need Reaction? The
one where 90% of my website is interactive? I've not written too many
of those, but the few I have, Catalyst has sufficed.</p>

<p>You're probably thinking now, that I just don't write the same kind of
applications/websites as others do. Thats possibly true.</p>

<p>But again, Agile ways of doing things suggest we write the minimal
amount of code we can get away with, to imlement the currently
required features. That we don't plan ahead and add more code for
potential features later, they will be re-thought anyway. That we
release early, and often, and gather feedback for improvement, and
then add new features.</p>

<p>Not forgetting to refactor. To upgrade, to replace the entire
framework if needed.</p>

<h2>To be practical</h2>

<p>I think, what I'm looking for is, a guide for newcomers to explain and
help ths progression. How to upgrade your site or code, from a few
pages, to some dynamic bits, to a full blown interactive site. Or even
not, not every site wants or needs to go that far. Not all code needs
to be able to use email.</p>

<p>There seem to exist many articles on how to write this complex code,
but not enough that explain how to come to the conclusion that you
need it.</p>

<p>Maybe this is also why there are still many many more people writing
about how to do CGI scripts in Perl, than how to use Moose. The
transition is missing.</p>

<p>(With thanks to <a href="http://www.ted.com/index.php/talks/elizabeth_gilbert_on_genius.html">Elizabeth Gilbert on nurturing creativity</a>)</p>

<p>Right, now I'm off to move the fledgling DBIx::Class website from some
hand written pages to ttree.</p>

<p>@public,programming,perl,thinking</p>
</div>
    </content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">public programming perl thinking</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-05-25T00:22:35Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-05-25T00:22:35Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">Jess Robinson</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:http://desert-island.me.uk:8888/~castaway/blog/are-we-going-to-need-it.html</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Modeling identity with KiokuX::User</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://feedproxy.google.com/~r/yuvalkogman/~3/doKYYURzuuQ/modeling-identity-with-kiokuxuser.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">If you're developing a KiokuDB based application then you probably already know about KiokuX::User. Here is a useful technique to keep your model flexible when you use it: instead of consuming the role in your high level user class, consume it in a class that models identity:


package MyFoo::Schema::Identity;
use Moose::Role;

has user =&gt; (
    isa      =&gt; "MyFoo::Schema::User",
    is       =&gt; "ro",
    required =&gt; 1,
);

package MyFoo::Schema::Identity::Username;
use Moose;

with qw(
    MyFoo::Schema::Identity
    KiokuX::User
);


MyFoo::Schema::User represents the actual user account, and any object doing the MyFoo::Schema::Identity role is an identity for such a user.

Keeping the two separated will allow you a number of freedoms:


Accounts can be consolidated or migrated easily
You can add support for additional authentication schemes
You can rename users but keep the usernames as primary keys (needed for backends for which uniqueness constraints cannot be specified) 


Obviously you should also keep a set of identities in each user object.</summary>
    <content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;If you're developing a &lt;a href="http://www.iinteractive.com/kiokudb/"&gt;KiokuDB&lt;/a&gt; based &lt;a href="http://blog.woobling.org/2009/05/using-kiokudb-in-catalyst-applications.html"&gt;application&lt;/a&gt; then you probably already know about &lt;a href="http://search.cpan.org/perldoc?KiokuX::User"&gt;&lt;tt&gt;KiokuX::User&lt;/tt&gt;&lt;/a&gt;. Here is a useful technique to keep your model flexible when you use it: instead of consuming the role in your high level user class, consume it in a class that models &lt;em&gt;identity&lt;/em&gt;:&lt;/p&gt;

&lt;pre id="fake-gist-114676 " class="fake-gist"&gt;&lt;code&gt;
package MyFoo::Schema::Identity;
use Moose::Role;

has user =&amp;gt; (
    isa      =&amp;gt; "MyFoo::Schema::User",
    is       =&amp;gt; "ro",
    required =&amp;gt; 1,
);

package MyFoo::Schema::Identity::Username;
use Moose;

with qw(
    MyFoo::Schema::Identity
    KiokuX::User
);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;tt&gt;MyFoo::Schema::User&lt;/tt&gt; represents the actual user account, and any object doing the &lt;tt&gt;MyFoo::Schema::Identity&lt;/tt&gt; role is an identity for such a user.&lt;/p&gt;

&lt;p&gt;Keeping the two separated will allow you a number of freedoms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accounts can be consolidated or migrated easily&lt;/li&gt;
&lt;li&gt;You can add support for additional authentication schemes&lt;/li&gt;
&lt;li&gt;You can rename users but keep the usernames as primary keys (needed for backends for which uniqueness constraints cannot be specified)&lt;/li&gt; 
&lt;/ul&gt;

&lt;p&gt;Obviously you should also keep a &lt;a href="http://search.cpan.org/perldoc?KiokuDB::Set"&gt;set&lt;/a&gt; of identities in each user object.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/doKYYURzuuQ"&gt;</content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">moose catalyst identity kiokudb authentication perl</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-05-20T06:44:00Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-05-20T06:44:00Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">nothingmuch</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:blogger.com,1999:blog-876358347971598886.post-7459778411414054181</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Authenticating Against Active Directory with Catalyst</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://www.onemogin.com/blog/639-authenticating-against-active-directory-with-catalyst" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">One of the more entertaining part of working in e-commerce is dealing with PCI compliance.  I say interesting because the standard is a mix of good things and inane things.  Regardless, it’s required.  One of the sections deals with authentication and authorization.  We’ve traditionally done that sort of business internally, but the newest PCI standards gave us quite a few requirements that we didn’t feel like adding.  Instead, we opted to offload that functionality onto our Windows machines.  We already had some experience with this, as our internal Trac talks to Active Directory to ease our administration when interfacing with the other departments.
Enough backstory.  I had some hassle getting Catalyst::Authentication::Store::LDAP working with Active Directory.  I wanted both authentication and roles, so here’s what I ended up with:

Plugin::Authentication:
    default_realm: members
    realms:
        members:
            credential:
                class: Password
                password_field: password
                password_type: self_check
            store:
                class: LDAP
                ldap_server: dc1:389
                ldap_server_options:
                    timeout: 30
                binddn: cn=SomeAccountYouSetup,ou=Accounts,dc=domain,dc=com
                bindpw: password
                user_basedn: ou=Accounts,dc=domain,dc=com
                user_filter: (userPrincipalName=%s)
                user_field: mail
                use_roles: 1
                role_basedn: ou=Groups,dc=domain,dc=com
                role_filter: (member=%s)
                role_scope: sub
                role_field: name
                role_value: dn
                role_search_as_user: 0
                role_search_options:
                    deref: always

I’m not really participating in Matt’s Iron Man but the flurry of Perl posting does leave me feeling a bit guilty for not saying a bit more about my language of choice.
UPDATE: I’ve changed the configuration a bit to show what you need to change.
</summary>
    <content xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>One of the more entertaining part of working in e-commerce is dealing with <a href="http://en.wikipedia.org/wiki/PCI_DSS">PCI compliance</a>.  I say interesting because the standard is a mix of good things and inane things.  Regardless, it’s required.  One of the sections deals with authentication and authorization.  We’ve traditionally done that sort of business internally, but the newest PCI standards gave us quite a few requirements that we didn’t feel like adding.  Instead, we opted to offload that functionality onto our Windows machines.  We already had some experience with this, as our internal <a href="http://trac.edgewall.org/">Trac</a> talks to Active Directory to ease our administration when interfacing with the other departments.</p>
<p>Enough backstory.  I had some hassle getting <a href="http://search.cpan.org/perldoc?Catalyst::Authentication::Store::LDAP">Catalyst::Authentication::Store::LDAP</a> working with Active Directory.  I wanted both authentication and roles, so here’s what I ended up with:</p>
<pre>
Plugin::Authentication:
    default_realm: members
    realms:
        members:
            credential:
                class: Password
                password_field: password
                password_type: self_check
            store:
                class: LDAP
                ldap_server: dc1:389
                ldap_server_options:
                    timeout: 30
                binddn: cn=SomeAccountYouSetup,ou=Accounts,dc=domain,dc=com
                bindpw: password
                user_basedn: ou=Accounts,dc=domain,dc=com
                user_filter: (userPrincipalName=%s)
                user_field: mail
                use_roles: 1
                role_basedn: ou=Groups,dc=domain,dc=com
                role_filter: (member=%s)
                role_scope: sub
                role_field: name
                role_value: dn
                role_search_as_user: 0
                role_search_options:
                    deref: always
</pre>
<p>I’m not really participating in <a href="http://www.shadowcat.co.uk/blog/matt-s-trout/iron-man/">Matt’s Iron Man</a> but the flurry of Perl posting does leave me feeling a bit guilty for not saying a bit more about my language of choice.</p>
<p><b>UPDATE:</b> I’ve changed the configuration a bit to show what you need to change.</p>
</div>
    </content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">Catalyst Code Languages Perl Windows Work</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-05-15T00:09:43Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-05-15T00:09:43Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">gphat</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:http://www.onemogin.com/blog/?p=639</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Under the palm tree (software-diy.html)</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://desert-island.me.uk/~castaway/blog/software-diy.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">Software DIY

At work, we have a bunch of in-house written, from-scratch (more or
less), software. As we're a software house, this isn't terribly
surprising, you might think.

However the software I'm talking about isn't the stuff we sell. It's
the basic code that holds up the website. There's an entire
self-written CMS, forms system, publishing system and a host of other
things. Most of this stuff evolved, from simple CGI scripts written
years ago, relying on text files and databases and so on. Some of
those .cgi scripts even still exist in remote corners.

Larger and frequently used systems have been refactored into more
hands-off tools, optimised for minimal maintenance.

Smaller systems languish, seemingly not enough used to refactor and
improve. And yet they waste the time of us workers, more than we'd
like.

Managements idea is to replace everything with some off-the-shelf
pre-written software, and all will be good. This is of course somewhat
of a pipe-dream, one which the people actually running that project
are quite aware of. It will need customising, of course.

So there's two extremes: Software we've written from scratch, and
software we just install, or pay for hosted. Where is the in-between
layer? I'm thinking what we need more of is mostly-done solutions,
components. Things like Catalyst plugins and similar come close, but
even those are often self-contained. How do I integrate, for example,
MojoMojo (wiki) and Angerwhale (blog) so that both use the same user
source? Ok, those are both classed as complete applications, but
that's my problem. I want them as parts of a whole.

Anyway, all this rambling, what I actually want to get started on is:

We have a system for writing forms, another one that builds a calendar
of events, and a third that stores training courses and their
dates/prices. None of these integrate with the other, and they're all
updated by hand, that is, by programmers, not by people running the
events/trainings.

After stumbling around the internet for a while looking for a
plausible off-the-shelf solution, I decided to just write one (this is
how frustrating finding software has become..) I did find a couple of
not too terrible sounding ones, but they appear to be all hosted. For
eg: Tendenci, which is
actually part of a CMS.

So far I've managed to write a simple (i.e. not terribly normalised,
but sufficient to reproduce existing systems) DB schema, and a
somewhat bare Catalyst app. Now I need to make an admin
interface/controller, and one to actually display the events list and
the sign-up forms.

@public,perl,ironman
</summary>
    <content xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><h1>Software DIY</h1>

<p>At work, we have a bunch of in-house written, from-scratch (more or
less), software. As we're a software house, this isn't terribly
surprising, you might think.</p>

<p>However the software I'm talking about isn't the stuff we sell. It's
the basic code that holds up the website. There's an entire
self-written CMS, forms system, publishing system and a host of other
things. Most of this stuff evolved, from simple CGI scripts written
years ago, relying on text files and databases and so on. Some of
those .cgi scripts even still exist in remote corners.</p>

<p>Larger and frequently used systems have been refactored into more
hands-off tools, optimised for minimal maintenance.</p>

<p>Smaller systems languish, seemingly not enough used to refactor and
improve. And yet they waste the time of us workers, more than we'd
like.</p>

<p>Managements idea is to replace everything with some off-the-shelf
pre-written software, and all will be good. This is of course somewhat
of a pipe-dream, one which the people actually running that project
are quite aware of. It will need customising, of course.</p>

<p>So there's two extremes: Software we've written from scratch, and
software we just install, or pay for hosted. Where is the in-between
layer? I'm thinking what we need more of is mostly-done solutions,
components. Things like Catalyst plugins and similar come close, but
even those are often self-contained. How do I integrate, for example,
MojoMojo (wiki) and Angerwhale (blog) so that both use the same user
source? Ok, those are both classed as complete applications, but
that's my problem. I want them as parts of a whole.</p>

<p>Anyway, all this rambling, what I actually want to get started on is:</p>

<p>We have a system for writing forms, another one that builds a calendar
of events, and a third that stores training courses and their
dates/prices. None of these integrate with the other, and they're all
updated by hand, that is, by programmers, not by people running the
events/trainings.</p>

<p>After stumbling around the internet for a while looking for a
plausible off-the-shelf solution, I decided to just write one (this is
how frustrating finding software has become..) I did find a couple of
not too terrible sounding ones, but they appear to be all hosted. For
eg: <a href="http://www.tendenci.com/en/cev/lists/">Tendenci</a>, which is
actually part of a CMS.</p>

<p>So far I've managed to write a simple (i.e. not terribly normalised,
but sufficient to reproduce existing systems) DB schema, and a
somewhat bare Catalyst app. Now I need to make an admin
interface/controller, and one to actually display the events list and
the sign-up forms.</p>

<p>@public,perl,ironman</p>
</div>
    </content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">public perl ironman</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-05-13T17:10:23Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-05-13T17:10:23Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">Jess Robinson</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:http://desert-island.me.uk:8888/~castaway/blog/software-diy.html</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Using KiokuDB in Catalyst applications</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://feedproxy.google.com/~r/yuvalkogman/~3/WgrIKp4wsm8/using-kiokudb-in-catalyst-applications.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">Using KiokuDB with Catalyst is very easy. This article sums up a few lessons learned from the last several apps we've developed at my workplace, and introduces the modules we refactored out of them.

Let's write an app is called Kitten::Friend, in which kittens partake in a social network and upload pictures of vases they've broken.

We generally follow these rules for organizing our code:


Catalyst stuff goes under Kitten::Friend::Web::.
Reusable app model code goes under Kitten::Friend::Model::.
The actual domain objects go under Kitten::Friend::Schema::, for instance Kitten::Friend::Schema::Vase. Using DBIx::Class::Schema these would be the table classes.


Anything that is not dependent on the Catalyst environment (as much code as possible) is kept separate from it. This means that we can use our KiokuDB model with all the convenience methods for unit testing or scripts, without configuring the Catalyst specific bits.
Functionality relating to how the app actually behaves is put in the Schema namespace. We try to keep this code  quite pure.
Glue code and helper methods go in the Model namespace. This separation helps us to refactor and adapt the code quite easily.

So let's start with the schema objects. Let's say we have two classes. The first is Kitten::Friend::Schema::Kitten:


package Kitten::Friend::Schema::Kitten;
use Moose;

use Kitten::Friend::Schema::Vase;

use KiokuDB::Set;

use KiokuDB::Util qw(set);

use namespace::autoclean;

with qw(KiokuX::User);    # provides 'id' and 'password' attributes

has name =&gt; (
    isa      =&gt; "Str",
    is       =&gt; "ro",
    required =&gt; 1,
);

has friends =&gt; (
    isa     =&gt; "KiokuDB::Set",
    is      =&gt; "ro",
    lazy    =&gt; 1,
    default =&gt; sub { set() },    # empty set
);

has vases =&gt; (
    isa     =&gt; "KiokuDB::Set",
    is      =&gt; "ro",
    lazy    =&gt; 1,
    default =&gt; sub { set() },
);

sub new_vase {
    my ( $self, @args ) = @_;

    my $vase = Kitten::Friend::Schema::Vase-&gt;new(
        owner =&gt; $self,
        @args,
    );

    $self-&gt;vases-&gt;insert($vase);

    return $vase;
}

sub add_friend {
    my ( $self, $friend ) = @_;

    $self-&gt;friends-&gt;insert($friend);
}

1;

I've used the KiokuX::User role to provide the Kitten object with some standard attributes for user objects. This will be used later to provide authentication support.

The second class is Kitten::Friend::Schema::Vase:


package Kitten::Friend::Schema::Vase;
use Moose;

use MooseX::AttributeHelpers;
use URI;

use namespace::autoclean;

has pictures =&gt; (
    metaclass =&gt; "Collection::Array",
    isa       =&gt; "ArrayRef[URI]",
    is        =&gt; "ro",
    default   =&gt; sub { [] },
    provides  =&gt; {
        push =&gt; "add_picture",
    },
);

has owner =&gt; (
    isa      =&gt; "Kitten::Friend::Schema::Kitten",
    is       =&gt; "ro",
    required =&gt; 1,
);

1;

Now let's write a unit test:


use strict;
use warnings;

use Test::More 'no_plan';

use KiokuX::User::Util qw(crypt_password);

use ok 'Kitten::Friend::Schema::Kitten';

my $kitten = Kitten::Friend::Schema::Kitten-&gt;new(
    name     =&gt; "Snookums",
    id       =&gt; "cutesy843",
    password =&gt; crypt_password("luvt00na"),
);

isa_ok( $kitten, "Kitten::Friend::Schema::Kitten" );

is( $kitten-&gt;name, "Snookums", "name attribute" );

ok( $kitten-&gt;check_password("luvt00na"), "password check" );
ok( !$kitten-&gt;check_password("bathtime"), "bad password" );

is_deeply( [ $kitten-&gt;friends-&gt;members ], [ ], "no friends" );
is_deeply( [ $kitten-&gt;vases-&gt;members ], [ ], "no no vases" );

my $vase = $kitten-&gt;new_vase(
    pictures =&gt; [ URI-&gt;new("http://icanhaz.com/broken_vase") ],
);

isa_ok( $vase, "Kitten::Friend::Schema::Vase" );

is_deeply( [ $kitten-&gt;vases-&gt;members ], [ $vase ], "new vase added" );



This test obviously runs completely independently of either Catalyst or KiokuDB.

The next step is to set up the model. We use KiokuX::Model as our model base class. The model class usually contains helper methods, like txn_do call wrappers and various other storage oriented tasks we want to abstract away. This way the web app code and scripts get a simpler API that takes care of as many persistence details as possible.


package Kitten::Friend::Model::KiokuDB;
use Moose;

extends qw(KiokuX::Model);

sub insert_kitten {
    my ( $self, $kitten ) = @_;

    my $id = $self-&gt;txn_do(sub {
        $self-&gt;store($kitten);
    });

    return $id;
}

1;

We can write a t/model.t to try this out:


use strict;
use warnings;

use Test::More 'no_plan';

use ok 'Kitten::Friend::Model::KiokuDB';

my $m = Kitten::Friend::Model::KiokuDB-&gt;new( dsn =&gt; "hash" );

{
    my $s = $m-&gt;new_scope;

    my $id = $m-&gt;insert_kitten(
         Kitten::Friend::Schema::Kitten-&gt;new(
            name     =&gt; "Kitteh",
            id       =&gt; "kitteh",
            password =&gt; crypt_password("s33krit"),
        ),
    );

    ok( $id, "got an ID" );

    my $kitten = $m-&gt;lookup($id);

    isa_ok( $kitten, "Kitten::Friend::Schema::Kitten", "looked up object" );
}



Next up is gluing this into the Catalyst app itself. I'm assuming you generated the app structure with catalyst.pl Kitten::Friend::Web. Create Kitten::Friend::Web::Model::KiokuDB as a subclass of Catalyst::Model::KiokuDB:


package Kitten::Friend::Web::Model::KiokuDB;
use Moose;

use Kitten::Friend::Model::KiokuDB;

BEGIN { extends qw(Catalyst::Model::KiokuDB) }

has '+model_class' =&gt; ( default =&gt; "Kitten::Friend::Model::KiokuDB" );

1;

And then configure a DSN in your Web.pm or configuration file:


&gt;Model KiokuDB&lt;
    dsn dbi:SQLite:dbname=root/db
&gt;/Model&lt;

That's all that's necessary to glue our Catalyst independent model code into the web app part.

Your model methods can be called as:


my $m = $c-&gt;model("kiokudb");

my $inner = $m-&gt;model

$inner-&gt;insert_kitten($kitten);

In the future I might consider adding an AUTOLOAD method, but you can also just extend the model attribute of Catalyst::Model::KiokuDB to provide more delegations (currently it only delegates KiokuDB::Role::API).

If you'd like to use Catalyst::Plugin::Authentication, configure it as follows:


__PACKAGE__-&gt;config(
    'Plugin::Authentication' =&gt; {
        realms =&gt; {
            default =&gt; {
                credential =&gt; {
                    class         =&gt; 'Password',
                    password_type =&gt; 'self_check'
                },
                store =&gt; {
                    class      =&gt; 'Model::KiokuDB',
                    model_name =&gt; "kiokudb",
                }
            }
        }
    },
);

And then you can let your kittens log in to the website:


my $user = eval {
    $c-&gt;authenticate({
        id       =&gt; $id,
        password =&gt; $password,
    });
};

if ( $user ) {
    $c-&gt;response-&gt;body( "Hello " . $user-&gt;get_object-&gt;name )
}

Some bonus features of the Catalyst model:


It calls new_scope for you, once per request
It tracks leaked objects and reports them in Debug mode. Circular structures are a bit tricky to get right if you aren't used to them so this is a big help.
</summary>
    <content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;Using &lt;a href="http://www.iinteractive.com/kiokudb/"&gt;KiokuDB&lt;/a&gt; with &lt;a href="http://www.catalystframework.org/"&gt;Catalyst&lt;/a&gt; is very easy. This article sums up a few lessons learned from the last several apps we've developed at my workplace, and introduces the modules we refactored out of them.&lt;/p&gt;

&lt;p&gt;Let's write an app is called &lt;tt&gt;Kitten::Friend&lt;/tt&gt;, in which kittens partake in a social network and upload pictures of vases they've broken.&lt;/p&gt;

&lt;p&gt;We generally follow these rules for organizing our code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Catalyst stuff goes under &lt;tt&gt;Kitten::Friend::Web::&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;Reusable app model code goes under &lt;tt&gt;Kitten::Friend::Model::&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;The actual domain objects go under &lt;tt&gt;Kitten::Friend::Schema::&lt;/tt&gt;, for instance &lt;tt&gt;Kitten::Friend::Schema::Vase&lt;/tt&gt;. Using &lt;tt&gt;&lt;a href="http://search.cpan.org/perldoc?DBIx::Class::Schema"&gt;DBIx::Class::Schema&lt;/a&gt;&lt;/tt&gt; these would be the table classes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anything that is not dependent on the Catalyst environment (as much code as possible) is kept separate from it. This means that we can use our KiokuDB model with all the convenience methods for unit testing or scripts, without configuring the Catalyst specific bits.&lt;/p&gt;
&lt;p&gt;Functionality relating to how the app actually behaves is put in the &lt;tt&gt;Schema&lt;/tt&gt; namespace. We try to keep this code  quite pure.&lt;/p&gt;
&lt;p&gt;Glue code and helper methods go in the &lt;tt&gt;Model&lt;/tt&gt; namespace. This separation helps us to refactor and adapt the code quite easily.&lt;/p&gt;

&lt;p&gt;So let's start with the schema objects. Let's say we have two classes. The first is &lt;tt&gt;Kitten::Friend::Schema::Kitten&lt;/tt&gt;:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-107569"&gt;&lt;code&gt;
package Kitten::Friend::Schema::Kitten;
use Moose;

use Kitten::Friend::Schema::Vase;

use KiokuDB::Set;

use KiokuDB::Util qw(set);

use namespace::autoclean;

with qw(KiokuX::User);    # provides 'id' and 'password' attributes

has name =&amp;gt; (
    isa      =&amp;gt; "Str",
    is       =&amp;gt; "ro",
    required =&amp;gt; 1,
);

has friends =&amp;gt; (
    isa     =&amp;gt; "KiokuDB::Set",
    is      =&amp;gt; "ro",
    lazy    =&amp;gt; 1,
    default =&amp;gt; sub { set() },    # empty set
);

has vases =&amp;gt; (
    isa     =&amp;gt; "KiokuDB::Set",
    is      =&amp;gt; "ro",
    lazy    =&amp;gt; 1,
    default =&amp;gt; sub { set() },
);

sub new_vase {
    my ( $self, @args ) = @_;

    my $vase = Kitten::Friend::Schema::Vase-&amp;gt;new(
        owner =&amp;gt; $self,
        @args,
    );

    $self-&amp;gt;vases-&amp;gt;insert($vase);

    return $vase;
}

sub add_friend {
    my ( $self, $friend ) = @_;

    $self-&amp;gt;friends-&amp;gt;insert($friend);
}

1;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I've used the &lt;tt&gt;&lt;a href="http://search.cpan.org/perldoc?KiokuX::User"&gt;KiokuX::User&lt;/a&gt;&lt;/tt&gt; role to provide the Kitten object with some standard attributes for user objects. This will be used later to provide authentication support.&lt;/p&gt;

&lt;p&gt;The second class is &lt;tt&gt;Kitten::Friend::Schema::Vase&lt;/tt&gt;:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-107570"&gt;&lt;code&gt;
package Kitten::Friend::Schema::Vase;
use Moose;

use MooseX::AttributeHelpers;
use URI;

use namespace::autoclean;

has pictures =&amp;gt; (
    metaclass =&amp;gt; "Collection::Array",
    isa       =&amp;gt; "ArrayRef[URI]",
    is        =&amp;gt; "ro",
    default   =&amp;gt; sub { [] },
    provides  =&amp;gt; {
        push =&amp;gt; "add_picture",
    },
);

has owner =&amp;gt; (
    isa      =&amp;gt; "Kitten::Friend::Schema::Kitten",
    is       =&amp;gt; "ro",
    required =&amp;gt; 1,
);

1;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now let's write a unit test:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-107571"&gt;&lt;code&gt;
use strict;
use warnings;

use Test::More 'no_plan';

use KiokuX::User::Util qw(crypt_password);

use ok 'Kitten::Friend::Schema::Kitten';

my $kitten = Kitten::Friend::Schema::Kitten-&amp;gt;new(
    name     =&amp;gt; "Snookums",
    id       =&amp;gt; "cutesy843",
    password =&amp;gt; crypt_password("luvt00na"),
);

isa_ok( $kitten, "Kitten::Friend::Schema::Kitten" );

is( $kitten-&amp;gt;name, "Snookums", "name attribute" );

ok( $kitten-&amp;gt;check_password("luvt00na"), "password check" );
ok( !$kitten-&amp;gt;check_password("bathtime"), "bad password" );

is_deeply( [ $kitten-&amp;gt;friends-&amp;gt;members ], [ ], "no friends" );
is_deeply( [ $kitten-&amp;gt;vases-&amp;gt;members ], [ ], "no no vases" );

my $vase = $kitten-&amp;gt;new_vase(
    pictures =&amp;gt; [ URI-&amp;gt;new("http://icanhaz.com/broken_vase") ],
);

isa_ok( $vase, "Kitten::Friend::Schema::Vase" );

is_deeply( [ $kitten-&amp;gt;vases-&amp;gt;members ], [ $vase ], "new vase added" );

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This test obviously runs completely independently of either Catalyst or KiokuDB.&lt;/p&gt;

&lt;p&gt;The next step is to set up the model. We use &lt;tt&gt;&lt;a href="http://search.cpan.org/perldoc?KiokuX::Model"&gt;KiokuX::Model&lt;/a&gt;&lt;/tt&gt; as our model base class. The model class usually contains helper methods, like &lt;tt&gt;txn_do&lt;/tt&gt; call wrappers and various other storage oriented tasks we want to abstract away. This way the web app code and scripts get a simpler API that takes care of as many persistence details as possible.&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-108072"&gt;&lt;code&gt;
package Kitten::Friend::Model::KiokuDB;
use Moose;

extends qw(KiokuX::Model);

sub insert_kitten {
    my ( $self, $kitten ) = @_;

    my $id = $self-&amp;gt;txn_do(sub {
        $self-&amp;gt;store($kitten);
    });

    return $id;
}

1;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can write a &lt;tt&gt;t/model.t&lt;/tt&gt; to try this out:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-107576"&gt;&lt;code&gt;
use strict;
use warnings;

use Test::More 'no_plan';

use ok 'Kitten::Friend::Model::KiokuDB';

my $m = Kitten::Friend::Model::KiokuDB-&amp;gt;new( dsn =&amp;gt; "hash" );

{
    my $s = $m-&amp;gt;new_scope;

    my $id = $m-&amp;gt;insert_kitten(
         Kitten::Friend::Schema::Kitten-&amp;gt;new(
            name     =&amp;gt; "Kitteh",
            id       =&amp;gt; "kitteh",
            password =&amp;gt; crypt_password("s33krit"),
        ),
    );

    ok( $id, "got an ID" );

    my $kitten = $m-&amp;gt;lookup($id);

    isa_ok( $kitten, "Kitten::Friend::Schema::Kitten", "looked up object" );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next up is gluing this into the Catalyst app itself. I'm assuming you generated the app structure with &lt;tt&gt;catalyst.pl Kitten::Friend::Web&lt;/tt&gt;. Create &lt;tt&gt;Kitten::Friend::Web::Model::KiokuDB&lt;/tt&gt; as a subclass of &lt;tt&gt;&lt;a href="http://search.cpan.org/perldoc?Catalyst::Model::KiokuDB"&gt;Catalyst::Model::KiokuDB&lt;/a&gt;&lt;/tt&gt;:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-108073"&gt;&lt;code&gt;
package Kitten::Friend::Web::Model::KiokuDB;
use Moose;

use Kitten::Friend::Model::KiokuDB;

BEGIN { extends qw(Catalyst::Model::KiokuDB) }

has '+model_class' =&amp;gt; ( default =&amp;gt; "Kitten::Friend::Model::KiokuDB" );

1;&lt;/code&gt;&lt;/pre&gt;

And then configure a DSN in your &lt;tt&gt;Web.pm&lt;/tt&gt; or configuration file:

&lt;pre class="fake-gist" id="fake-gist-107600"&gt;
&amp;gt;Model KiokuDB&amp;lt;
    dsn dbi:SQLite:dbname=root/db
&amp;gt;/Model&amp;lt;&lt;/pre&gt;

&lt;p&gt;That's all that's necessary to glue our Catalyst independent model code into the web app part.&lt;/p&gt;

&lt;p&gt;Your model methods can be called as:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-107581"&gt;&lt;code&gt;
my $m = $c-&amp;gt;model("kiokudb");

my $inner = $m-&amp;gt;model

$inner-&amp;gt;insert_kitten($kitten);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the future I might consider adding an &lt;tt&gt;AUTOLOAD&lt;/tt&gt; method, but you can also just extend the &lt;tt&gt;model&lt;/tt&gt; attribute of &lt;tt&gt;Catalyst::Model::KiokuDB&lt;/tt&gt; to provide more delegations (currently it only delegates &lt;tt&gt;&lt;a href="http://search.cpan.org/perldoc?KiokuDB::Role::API"&gt;KiokuDB::Role::API&lt;/a&gt;&lt;/tt&gt;).&lt;/p&gt;

&lt;p&gt;If you'd like to use &lt;tt&gt;&lt;a href="http://search.cpan.org/perldoc?Catalyst::Plugin::Authentication"&gt;Catalyst::Plugin::Authentication&lt;/a&gt;&lt;/tt&gt;, configure it as follows:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-107630"&gt;&lt;code&gt;
__PACKAGE__-&amp;gt;config(
    'Plugin::Authentication' =&amp;gt; {
        realms =&amp;gt; {
            default =&amp;gt; {
                credential =&amp;gt; {
                    class         =&amp;gt; 'Password',
                    password_type =&amp;gt; 'self_check'
                },
                store =&amp;gt; {
                    class      =&amp;gt; 'Model::KiokuDB',
                    model_name =&amp;gt; "kiokudb",
                }
            }
        }
    },
);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then you can let your kittens log in to the website:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-107578"&gt;&lt;code&gt;
my $user = eval {
    $c-&amp;gt;authenticate({
        id       =&amp;gt; $id,
        password =&amp;gt; $password,
    });
};

if ( $user ) {
    $c-&amp;gt;response-&amp;gt;body( "Hello " . $user-&amp;gt;get_object-&amp;gt;name )
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Some bonus features of the Catalyst model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It calls &lt;tt&gt;new_scope&lt;/tt&gt; for you, once per request&lt;/li&gt;
&lt;li&gt;It tracks leaked objects and reports them in Debug mode. Circular structures are a bit tricky to get right if you aren't used to them so this is a big help.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/WgrIKp4wsm8"&gt;</content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">moose catalyst kiokudb perl</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-05-06T14:30:00Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-05-06T14:30:00Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">nothingmuch</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:blogger.com,1999:blog-876358347971598886.post-8387801917490356518</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Projects Updates and QA Tools</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://bricas.vox.com/library/post/projects-updates-and-qa-tools.html?_c=feed-atom" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">
            
                
         NB: This is my first post in the EPO Iron Man challenge. (Warning: contains some expletives)  First and foremost, the long awaited Catalyst 5.8 is out! My mind-share has primarily been with the 5.7x series so I've been pretty much out of the loop ...    
    Read and post comments   |   
    Send to a friend 


                
            
        </summary>
    <content xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
            
                <div xmlns="http://www.w3.org/1999/xhtml" xmlns:at="http://www.sixapart.com/ns/at">
         NB: This is my first post in the EPO Iron Man challenge. (Warning: contains some expletives)  First and foremost, the long awaited Catalyst 5.8 is out! My mind-share has primarily been with the 5.7x series so I've been pretty much out of the loop ...   <p> 
    <a href="http://bricas.vox.com/library/post/projects-updates-and-qa-tools.html?_c=feed-atom#comments">Read and post comments</a>   |   
    <a href="http://www.vox.com/share/6a00d09e62f541be2b0110167be06a860d?_c=feed-atom">Send to a friend</a> 
</p>

                </div>
            
        </div>
    </content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">perl catalyst text mode perl-qa</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-04-22T18:04:14Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-04-22T18:04:14Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">Brian</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:vox.com,2009-04-22:asset-6a00d09e62f541be2b0110167be06a860d</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Roles for FormHandler</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://perlalchemy.blogspot.com/2009/04/roles-for-formhandler.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">This is a more concrete version of the question from my last post.  This is a form defined in FormHandler:    package BookDB::Form::BookWithOwner;    use HTML::FormHandler::Moose;    extends 'HTML::FormHandler::Model::DBIC';    has '+item_class' =&gt; ( default =&gt; 'Author' );    has_field 'title' =&gt; ( type =&gt; 'Text', required =&gt; 1 );    has_field 'publisher' =&gt; ( type =&gt; 'Text', required =&gt; 1 );    has_field 'owner' =&gt; ( type =&gt; 'BookDB::Form::BookOwner' );This should be quite self-explanatory for anyone working with forms (and DBIC).Now - I think Model::DBIC should be just a role here, but that is just a side track.  The real question is about the fields here - ideally I would want that doing:with 'HTML::FormHandler::Model::DBIC';(this is after it is made a Role) - would add appriopriate methods to the fields - an example here could be validation of fields that need a unique value.  I would like to not need to change the definitions above to:has_field 'title' =&gt; ( type =&gt; 'Text::DBIC', required =&gt; 1 );Fields like 'owner' above which are Compound fields and work mostly like a form itself and need to load the options for SELECT boxes from the model, set the values of fields from a database row etc:    package BookDB::Form::BookOwner;    use HTML::FormHandler::Moose;    extends 'HTML::FormHandler::Field::Compound';    with 'HTML::FormHandler::Model::DBIC';    has '+item_class' =&gt; ( default =&gt; 'User' );    has_field 'user_name';    has_field 'fav_cat' =&gt; ( label =&gt; 'Favorite Book Category' );    has_field 'fav_book' =&gt; ( label =&gt; 'Favorite Book' );    has_field 'occupation';    has_field 'country' =&gt; ( type =&gt; 'Select' );Ideally this definition should not need 'HTML::FormHandler::Model::DBIC' - applying this role to the root form should be enough.</summary>
    <content xmlns="http://www.w3.org/2005/Atom" type="text">This is a more concrete version of the question from my last post.  This is a form defined in FormHandler:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    package BookDB::Form::BookWithOwner;&lt;br /&gt;&lt;br /&gt;    use HTML::FormHandler::Moose;&lt;br /&gt;    extends 'HTML::FormHandler::Model::DBIC';&lt;br /&gt;&lt;br /&gt;    has '+item_class' =&amp;gt; ( default =&amp;gt; 'Author' );&lt;br /&gt;&lt;br /&gt;    has_field 'title' =&amp;gt; ( type =&amp;gt; 'Text', required =&amp;gt; 1 );&lt;br /&gt;    has_field 'publisher' =&amp;gt; ( type =&amp;gt; 'Text', required =&amp;gt; 1 );&lt;br /&gt;    has_field 'owner' =&amp;gt; ( type =&amp;gt; 'BookDB::Form::BookOwner' );&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This should be quite self-explanatory for anyone working with forms (and DBIC).&lt;br /&gt;Now - I think Model::DBIC should be just a role here, but that is just a side track.  The real question is about the fields here - ideally I would want that doing:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;with 'HTML::FormHandler::Model::DBIC';&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;(this is after it is made a Role) - would add appriopriate methods to the fields - an example here could be validation of fields that need a unique value.  I would like to not need to change the definitions above to:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;has_field 'title' =&amp;gt; ( type =&amp;gt; 'Text::DBIC', required =&amp;gt; 1 );&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Fields like 'owner' above which are Compound fields and work mostly like a form itself and need to load the options for SELECT boxes from the model, set the values of fields from a database row etc:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    package BookDB::Form::BookOwner;&lt;br /&gt;&lt;br /&gt;    use HTML::FormHandler::Moose;&lt;br /&gt;    extends 'HTML::FormHandler::Field::Compound';&lt;br /&gt;    with 'HTML::FormHandler::Model::DBIC';&lt;br /&gt;&lt;br /&gt;    has '+item_class' =&amp;gt; ( default =&amp;gt; 'User' );&lt;br /&gt;&lt;br /&gt;    has_field 'user_name';&lt;br /&gt;    has_field 'fav_cat' =&amp;gt; ( label =&amp;gt; 'Favorite Book Category' );&lt;br /&gt;    has_field 'fav_book' =&amp;gt; ( label =&amp;gt; 'Favorite Book' );&lt;br /&gt;    has_field 'occupation';&lt;br /&gt;    has_field 'country' =&amp;gt; ( type =&amp;gt; 'Select' );&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Ideally this definition should not need 'HTML::FormHandler::Model::DBIC' - applying this role to the root form should be enough.&lt;div class="blogger-post-footer"&gt;&lt;img&gt;&lt;/div&gt;</content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/"></dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-04-04T09:14:00Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-04-04T09:14:00Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">zby</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:blogger.com,1999:blog-36345871.post-1618690407171981057</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Roles and data structures</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://perlalchemy.blogspot.com/2009/03/roles-and-data-structures.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">Let's say you have a tree like data structure, something not exactly so uniform as a tree but with enough uniformity that it makes sense that large part of the code is recursive.  My example is something representing an HTML Form for editing a complex data structure (with sub-forms etc.).  The main form code is used for inflating external data represetntation (key, value pairs) into internal objects and validating it.  But there are two additional 'aspects' of this form processing - this is generating the HTML of the form (with all the error indicators and messages) and saving the form data into the data store (by manipulating DBIx::Class schema for example).  So you have a tree-like data structure and three separate functionality areas related to it.  How do you structure the code?You can start with defining the data structure and one of the aspects as the 'primary package' - and then add the other aspects as (Moose) roles.  This is how it is started in FormHandler - the primary aspect here is the data processing and validation - then saving the the database is added as a role (so you can use it with different data store libraries DBIx::Class, Class::DBI and in the future all the other), the same with rendering - it is a role added to the form class.  This is all nice untill you realize that in this way you add the additional roles only to the main form object - but not to the fields (i.e. nodes in the tree) - so you can walk the fields and do the stuff - but you regress here to mostly procedural code.What we need is to somehow add this role globally to all the field and form classes used.</summary>
    <content xmlns="http://www.w3.org/2005/Atom" type="text">Let's say you have a tree like data structure, something not exactly so uniform as a tree but with enough uniformity that it makes sense that large part of the code is recursive.  My example is something representing an HTML Form for editing a complex data structure (with sub-forms etc.).  The main form code is used for inflating external data represetntation (key, value pairs) into internal objects and validating it.  But there are two additional 'aspects' of this form processing - this is generating the HTML of the form (with all the error indicators and messages) and saving the form data into the data store (by manipulating DBIx::Class schema for example).  So you have a tree-like data structure and three separate functionality areas related to it.  How do you structure the code?&lt;br /&gt;&lt;p&gt;&lt;br /&gt;You can start with defining the data structure and one of the aspects as the 'primary package' - and then add the other aspects as (&lt;a href="http://search.cpan.org/~drolsky/Moose-0.73/lib/Moose/Role.pm"&gt;Moose&lt;/a&gt;) roles.  This is how it is started in FormHandler - the primary aspect here is the data processing and validation - then saving the the database is added as a role (so you can use it with different data store libraries DBIx::Class, Class::DBI and in the future all the other), the same with rendering - it is a role added to the form class.  This is all nice untill you realize that in this way you add the additional roles only to the main form object - but not to the fields (i.e. nodes in the tree) - so you can walk the fields and do the stuff - but you regress here to mostly procedural code.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;What we need is to somehow add this role globally to all the field and form classes used.&lt;div class="blogger-post-footer"&gt;&lt;img&gt;&lt;/div&gt;</content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/"></dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-03-31T07:12:00Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-03-31T07:12:00Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">zby</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:blogger.com,1999:blog-36345871.post-1330650453157623957</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Under the palm tree (auto-listing-inherited-methods-in-pod.html)</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://desert-island.me.uk/~castaway/blog/auto-listing-inherited-methods-in-pod.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">Auto-listing inherited methods in POD

You write a module, or a whole suite of modules, and (hopefully)
nicely document all the methods in the classes next to the
code. Great!

Only now the problem is that the module suite is using some best
practices, and builds re-usable base classes on top of re-usable base
classes, until the actual user-usable classes are just
icing-on-the-cake layers on top.

Now your users have to figure out which methods on their resulting
objects come from which of your base-base classes, and dive into
various different pieces of documentation to piece together the
methods they can call.

No longer!

Having been annoyed enough by this sort of POD wrangling already,
theorbtwo came up with Pod::Inherit to help the module writers
improve their documentation. Run it with the name of a class or the
lib directory for your distribution, every class is investigated to
determine which methods it contains, the inheritance tree is then
searched to determine which base class actually defines that
method. After the collection is complete, the POD from the original
file is written to a new file with the extension ".pod" and adds a
"INHERITED METHODS" section at the bottom (after all other sections,
before any section named LICENSE, AUTHORS and so on.

The INHERITED METHODS section consists of a list of classes the
current class inherits from, with a link to that class. It then lists
the names of the inherited methods. This will also include methods
that are outside the current distribution tree, for example if the
module inherits from Class::Accessor::Grouped, then "mkgroupaccessors" will be listed.

So, having waffled a lot, here's what the output looks like when we
run it over DBIx::Class:

DBIx::Class pod, inherited

Apache::Pod, proper linking

As an extra, I got annoyed enough at Apache::Pod for always linking to
search.cpan.org when displaying links in my local documentation, that
we came up with a way to have it figure out whether the link was in
the local tree of files, and link there, or whether it was a true
external link.

Unfortunately in singleton mode (i.e. just parsing a single file, as
it is when installed as an Apache PerlHandler), it can only guess by
recursing up the file tree until it finds a directory that doesn't
look like a class name. Unpretty, but works if you make the dirs all
lower-case (yes, pragmas don't count).

In batch mode however, it does have a good clue what its working on,
so there it knows exactly what it can link, and what not.

So having fixed that, we can run it over the DBIx::Class pod-inherited
docs, and get sane linking too!

DBIx::Class pod, inherited and linked sanely

How's that for annoyed programmers?

@public,perl,pod,dbix-class,dbic
</summary>
    <content xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><h1>Auto-listing inherited methods in POD</h1>

<p>You write a module, or a whole suite of modules, and (hopefully)
nicely document all the methods in the classes next to the
code. Great!</p>

<p>Only now the problem is that the module suite is using some best
practices, and builds re-usable base classes on top of re-usable base
classes, until the actual user-usable classes are just
icing-on-the-cake layers on top.</p>

<p>Now your users have to figure out which methods on their resulting
objects come from which of your base-base classes, and dive into
various different pieces of documentation to piece together the
methods they can call.</p>

<p>No longer!</p>

<p>Having been annoyed enough by this sort of POD wrangling already,
theorbtwo came up with Pod::Inherit to help the module writers
improve their documentation. Run it with the name of a class or the
lib directory for your distribution, every class is investigated to
determine which methods it contains, the inheritance tree is then
searched to determine which base class actually defines that
method. After the collection is complete, the POD from the original
file is written to a new file with the extension ".pod" and adds a
"INHERITED METHODS" section at the bottom (after all other sections,
before any section named LICENSE, AUTHORS and so on.</p>

<p>The INHERITED METHODS section consists of a list of classes the
current class inherits from, with a link to that class. It then lists
the names of the inherited methods. This will also include methods
that are outside the current distribution tree, for example if the
module inherits from <a href="http://search.cpan.org/perldoc?Class::Accessor::Grouped">Class::Accessor::Grouped</a>, then "mk<em>group</em>accessors" will be listed.</p>

<p>So, having waffled a lot, here's what the output looks like when we
run it over <a href="http://search.cpan.org/perldoc?DBIx::Class">DBIx::Class</a>:</p>

<p><a href="http://desert-island.me.uk:8888/perldoc/dbic-pod/DBIx/Class.pod">DBIx::Class pod, inherited</a></p>

<h2>Apache::Pod, proper linking</h2>

<p>As an extra, I got annoyed enough at Apache::Pod for always linking to
search.cpan.org when displaying links in my local documentation, that
we came up with a way to have it figure out whether the link was in
the local tree of files, and link there, or whether it was a true
external link.</p>

<p>Unfortunately in singleton mode (i.e. just parsing a single file, as
it is when installed as an Apache PerlHandler), it can only guess by
recursing up the file tree until it finds a directory that doesn't
look like a class name. Unpretty, but works if you make the dirs all
lower-case (yes, pragmas don't count).</p>

<p>In batch mode however, it does have a good clue what its working on,
so there it knows exactly what it can link, and what not.</p>

<p>So having fixed that, we can run it over the DBIx::Class pod-inherited
docs, and get sane linking too!</p>

<p><a href="http://desert-island.me.uk:8888/~castaway/dbic-html/DBIx/Class.html">DBIx::Class pod, inherited and linked sanely</a></p>

<p>How's that for annoyed programmers?</p>

<p>@public,perl,pod,dbix-class,dbic</p>
</div>
    </content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">public perl pod dbix-class dbic</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-03-30T20:49:44Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-03-30T20:49:44Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">Jess Robinson</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:http://desert-island.me.uk:8888/~castaway/blog/auto-listing-inherited-methods-in-pod.html</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Ernst, Angerwhale, the Future of Perl Web Frameworks, and Deleted Email</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://blog.jrock.us/articles/Ernst%2C%20Angerwhale%2C%20the%20Future%20of%20Perl%20Web%20Frameworks%2C%20and%20Deleted%20Email.pod" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">
The other day, someone emailed me about
Ernst.  I thought I marked the
email as "reply to soon", but I actually deleted it.  Oops.  Anyway,
if you are that person, please get in contact with me again, I'm
really sorry for deleting your email.
With that in mind, I thought I'd write a little about my plans for the
future with respect to Ernst.  Basically, the current version is a
prototype that I wrote to see what metadescription systems are all
about.  I liked the concept initially, and now that I've implemented
it, I like it even more.  The implementation, however, does have some
problems.  The biggest is that you have to use Ernst to use it.
This creates a metaclass compatibility pain point -- can a use Moose
class subclass an Ernst class?  Can Ernst roles be applied to
regular classes?  (The answer to all of these questions should be yes,
but in the current implementation, the answer is no.  Attributes in
roles can have metadescriptions, but must be regular Moose::Roles;
everything else has to be a class that says use Ernst instead of
use Moose.  This is dumb.)
Anyway, Moose has "metaroles" now, and using that feature will result
in a cleaner implementation.  The first step for a "real" Ernst will
be to fix that problem.  A Simple Matter Of Programming :)
With a solid implementation of the internals, a new set of problems
comes up:
Should there be separate classes that exist solely to describe a
class?  It is a pain to have HTML snippets inline with your class
attributes, after all -- but it is also messy to sequester them off
somewhere that would require a config file to load properly.  The idea
is to describe attributes and classes, and the class is the best
place to do that, but sometimes the descriptions are too verbose.
What should we do about this?
Should we use Moose's type constraint system?  As I was implementing
the first version, I was tempted to implement my own types.  Moose's
types were too inflexible at the time, I thought; I wanted types that
could be incrementally validated, and that understood that they would
both keep my program consistent ("HashRef[Str]") and be used to tell a
user that his data was not valid.  (A password type would be a String,
of course, but it also had other restrictions like "Your password
should be at least 8 characters long." and "Your password should
contain at least 42 numbers."  When generating a UI, you want to
present all errors at once and a single Perl code block just isn't
enough to do that; we need real introspection.)  Anyway, this is
another problem that Moose is solving; type constraints have received
a lot of love lately, and I think we can do everything we need there.
What should an "Interpreter" do? Right now, it is a class that has
an "interpret" method.  I think this is too flexible, as it doesn't
really abstract anything away.  You might as well just call it a
function.  We need to decide what interpreters should do, and then
determine what the common API should look like.  (There are
interpreters in the Ernst distribution now, but I really wasn't sure
what the API would look like when I was writing them.  I just made
them work.)
Basically, if you have thoughts, let's discuss them on #moose
(irc.perl.org).  Once these issues are worked out, we can write the
real implementation!
Speaking of the future, my "main project" right now is rewriting
Angerwhale.  Angerwhale started out as my
first "real" Perl and Catalyst project, and grew to actually have some
users.  Looking back, I really should have discouraged people from
using it -- too many ideas were experimental and turned out to not
work in real life.  (Do you really like PGP-signing your comments?  It
seems not; I only know of three people who post here that sign their
comments.  Everyone else stays anonymous.  This leads me to believe
that PGP-only authentication is a bad idea.)
Anyway, the idea for Angerwhale-ng (or Angerwhale 2, even though there
never was an Angerwhale 1), is to not be experimental anymore.  I
really want to create a real blogging platform, and replace
Wordpress and MT throughout the Internet.  Those platforms are too
hard to extend, are messy internally (and extensions are messier), try
too hard to be generic CMSes, and don't even have good support for
writing about programming.  (Nearly every Wordpress blog I see turns
quotation marks inside code snippets into smart-quotes.  WTF?)  It's
time to put a stop to that insanity and do blogging right.
So, my high-level goal is to create a platform that is cleanly
extensible in ways that I don't foresee.  Angerwhale 1 tried to do
this (and was pretty successful), but too many things required
knowledge of the internals.  I am aiming for something more
transparent and flexible.  Emacs is a great example of this.  Nobody
ever intended for Emacs to be an IRC client or mail reader.  But
thanks to the flexibility, those features arose naturally.  Someone
wanted them, and the tools to build them were already there.  So they
built them, and now everyone can have them.  That is how I want
Angerwhale to work.
The biggest factor contributing to the extensibility will be
KiokuDB.  There will be no
database schema; everything will be a Moose object in the database.
That means that an extension that wants to hook something can be a
role applied to an instance.  (Just like you were extending a Moose
class in memory.)  Users may not have an "openid" field by default,
but you can apply a role and then they will.  (But actually, this
specific case is better handled by delegation.  Although I want things
to be easy to extend without me providing explicit extension points, I
will try to provide as many explicit extension points as possible.
The goal is to be easily extensible AND to have very clean internals.)
Since there is no database schema to mess around with, flexibility is
easy.  The app doesn't know or care about your extensions; they Just
Work.  (KiokuDB also helps in other areas -- performance will be a lot
better than my ad-hoc file + attributes system that Angerwhale 1 uses.
KiokuDB is really fast, and scales well too.)
(One feature that doesn't fit into my narrative is that Angerwhale
will be a blogging platform -- one instance will be able to host many
blogs.  That means that we can make better use of memory; one blog may
take 300M of RAM, but 1000 blogs will only take 305M.  This means that
Angerwhale will be good for hosting individual blogs like this one,
but also good for hosting community sites like Planet Perl and use.perl.  I
do intend to provide a public blogging service for Perl bloggers as my
first deployment, and hopefully replace use.perl's aging journal
system without destroying the excellent community features.  You'll
also get Planet Perl for free.)
The next part of Angerwhale will be a new web framework.  It won't be
like the other new web frameworks, though; the goal is to unify all
the Perl web frameworks and provide a true framework framework for
everyone to build on.  (The goal of the other "new" web frameworks, it
seems, is to provide fewer features under the guise of "simplicity".
Forcing users to reinvent the wheel is not simplicity, though, and I
think this idea sucks.  Perl is about TMTOWTDI, not being told that
your way is wrong and that you should go fuck yourself if you don't
like my way.)
The framework will consist of 4 completely separate parts.  The first
is the "app engine", to support things that concern the entire
application.  It knows nothing about the web, and doesn't care. (So
you can use it in non-web daemons too.) It will provide features like
timed events ("clean my sessions table every hour"), an event loop (so
that you can fork, fetch web pages, or access your database without
blocking other requests), logging, and debugging tools (you can embed
a Stylish::REPL instance and introspect your live application).
It will be AnyEvent based, so you can freely choose between EV,
POE, or Event in your application.  (The other parts of the
framework, like Stylish::REPL, HTTP::Engine, AnyEvent::DBI,
and so on, all use AnyEvent, so the framework won't make any event
loop policy decisions for you.  That way you can use your favorite
event loop, or run code that already depends on one, inside the
framework.  This provides the most flexibility and reusability, and I
like the AnyEvent sugar a lot anyway. :)
The next part is the HTTP helper, HTTP::Engine.  This is what
actually glues the app to the web.  I am currently writing an
AnyEvent backend for HTTP::Engine, so that web IO is completely
non-blocking.
HTTP::Engine gives you the basic request/response capabilities, and
also provides middleware (debug screens, authentication, etc.).  It
knows how to talk to mod_perl, or be its own server, or be served with
FastCGI; so, as with Catalyst apps, this is something your application
doesn't need to worry about.  Develop with the embedded server, deploy
with FastCGI, it will all work.
The idea is that it will handle everything that is specific to the
web, but not specific to your application.  (If you haven't tried
HTTP::Engine yet, you should.  It's really easy to set up, and is a
great fit for applications that don't require a "real" framework, but
that you don't want to use CGI for.  And let's face it, you don't want
to use CGI for anything but the smallest toy apps. My
App::TemplateServer on CPAN uses it, so take a look.)
The third part of the framework is a component loader.  Current web
frameworks tend to load components "automatically", but this is not
always the most desirable approach.  Something like Bread::Board is
much better.  My framework will let you load components however you
want; you can do it Catalyst-style, use can use Bread::Board, or you
can just do it with some code.  Your choice.
At this point, you have a solid foundation for building a long-running
Perl application, you have a generic way of interacting with the web
(complete with niceties like middleware), and you have a solid way of
loading and configuring the application's components.  That leads us
to the last layer, the actual framework.
Basically, you can do what ever you want here.  I am planning on
making it possible to use existing Catalyst controllers in the
application, and to support Continuity.  (I have use cases where I
want both styles in my app -- Catalyst-style actions for the public
part, and Continuity actions in the administrative area.)
Stevan Little is currently working on a framework that is
document-based; you make objects that know how to be mutated and how
to render themselves, and the framework takes care of the rest.  This
will integrate cleanly with this framework, of course.
If you really don't like framework-y stuff, just use Path::Router
to assign function calls to URIs.  It's simple, easy to understand,
and you can dive into something more complex later, if you want to.
The best of all worlds.
So that's basically it -- the future of Perl web frameworks is
unification.  Users shouldn't have to commit to one way of thinking --
everything should work together.  That is my goal.
It's important to say that this isn't just pie on the sky -- I am
actively working on these projects (and not by myself, this is a
community project).
I will be talking about this stuff more throughout the year.  First at
NPW, and at YAPC::NA, YAPC::EU, and YAPC::Asia.  Hopefully by YAPC::EU
and YAPC::Asia, this will be code you can use in your own
applications!
Anyway, ping me on irc and let's chat!


</summary>
    <content xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <div class="pod">
<p>The other day, someone emailed me about
<a href="http://github.com/jrockway/ernst">Ernst</a>.  I thought I marked the
email as "reply to soon", but I actually deleted it.  Oops.  Anyway,
if you are that person, please get in contact with me again, I'm
really sorry for deleting your email.</p>
<p>With that in mind, I thought I'd write a little about my plans for the
future with respect to Ernst.  Basically, the current version is a
prototype that I wrote to see what metadescription systems are all
about.  I liked the concept initially, and now that I've implemented
it, I like it even more.  The implementation, however, does have some
problems.  The biggest is that you have to <code>use Ernst</code> to use it.
This creates a metaclass compatibility pain point -- can a <code>use Moose</code>
class subclass an Ernst class?  Can Ernst roles be applied to
regular classes?  (The answer to all of these questions should be yes,
but in the current implementation, the answer is no.  Attributes in
roles can have metadescriptions, but must be regular <code>Moose::Role</code>s;
everything else has to be a class that says <code>use Ernst</code> instead of
<code>use Moose</code>.  This is dumb.)</p>
<p>Anyway, Moose has "metaroles" now, and using that feature will result
in a cleaner implementation.  The first step for a "real" Ernst will
be to fix that problem.  A Simple Matter Of Programming :)</p>
<p>With a solid implementation of the internals, a new set of problems
comes up:</p>
<p><strong>Should there be separate classes that exist solely to describe a
class?</strong>  It is a pain to have HTML snippets inline with your class
attributes, after all -- but it is also messy to sequester them off
somewhere that would require a config file to load properly.  The idea
is to <i>describe</i> attributes and classes, and the class is the best
place to do that, but sometimes the descriptions are too verbose.
What should we do about this?</p>
<p><strong>Should we use Moose's type constraint system?</strong>  As I was implementing
the first version, I was tempted to implement my own types.  Moose's
types were too inflexible at the time, I thought; I wanted types that
could be incrementally validated, and that understood that they would
both keep my program consistent ("HashRef[Str]") and be used to tell a
user that his data was not valid.  (A password type would be a String,
of course, but it also had other restrictions like "Your password
should be at least 8 characters long." and "Your password should
contain at least 42 numbers."  When generating a UI, you want to
present all errors at once and a single Perl code block just isn't
enough to do that; we need real introspection.)  Anyway, this is
another problem that Moose is solving; type constraints have received
a lot of love lately, and I think we can do everything we need there.</p>
<p><strong>What should an "Interpreter" do?</strong> Right now, it is a class that has
an "interpret" method.  I think this is too flexible, as it doesn't
really abstract anything away.  You might as well just call it a
function.  We need to decide what interpreters should do, and then
determine what the common API should look like.  (There are
interpreters in the Ernst distribution now, but I really wasn't sure
what the API would look like when I was writing them.  I just made
them work.)</p>
<p>Basically, if you have thoughts, let's discuss them on <code>#moose</code>
(irc.perl.org).  Once these issues are worked out, we can write the
real implementation!</p>
<p>Speaking of the future, my "main project" right now is rewriting
<a href="http://www.angerwhale.org">Angerwhale</a>.  Angerwhale started out as my
first "real" Perl and Catalyst project, and grew to actually have some
users.  Looking back, I really should have discouraged people from
using it -- too many ideas were experimental and turned out to not
work in real life.  (Do you really like PGP-signing your comments?  It
seems not; I only know of three people who post here that sign their
comments.  Everyone else stays anonymous.  This leads me to believe
that PGP-only authentication is a bad idea.)</p>
<p>Anyway, the idea for Angerwhale-ng (or Angerwhale 2, even though there
never was an Angerwhale 1), is to not be experimental anymore.  I
really want to create a <i>real</i> blogging platform, and replace
Wordpress and MT throughout the Internet.  Those platforms are too
hard to extend, are messy internally (and extensions are messier), try
too hard to be generic CMSes, and don't even have good support for
writing about programming.  (Nearly every Wordpress blog I see turns
quotation marks inside code snippets into smart-quotes.  WTF?)  It's
time to put a stop to that insanity and do blogging <i>right</i>.</p>
<p>So, my high-level goal is to create a platform that is cleanly
extensible in ways that I don't foresee.  Angerwhale 1 tried to do
this (and was pretty successful), but too many things required
knowledge of the internals.  I am aiming for something more
transparent and flexible.  Emacs is a great example of this.  Nobody
ever intended for Emacs to be an IRC client or mail reader.  But
thanks to the flexibility, those features arose naturally.  Someone
wanted them, and the tools to build them were already there.  So they
built them, and now everyone can have them.  That is how I want
Angerwhale to work.</p>
<p>The biggest factor contributing to the extensibility will be
<a href="http://www.iinteractive.com/kiokudb/">KiokuDB</a>.  There will be no
database schema; everything will be a Moose object in the database.
That means that an extension that wants to hook something can be a
role applied to an instance.  (Just like you were extending a Moose
class in memory.)  Users may not have an "openid" field by default,
but you can apply a role and then they will.  (But actually, this
specific case is better handled by delegation.  Although I want things
to be easy to extend without me providing explicit extension points, I
will try to provide as many explicit extension points as possible.
The goal is to be easily extensible AND to have very clean internals.)
Since there is no database schema to mess around with, flexibility is
easy.  The app doesn't know or care about your extensions; they Just
Work.  (KiokuDB also helps in other areas -- performance will be a lot
better than my ad-hoc file + attributes system that Angerwhale 1 uses.
KiokuDB is really fast, and scales well too.)</p>
<p>(One feature that doesn't fit into my narrative is that Angerwhale
will be a blogging platform -- one instance will be able to host many
blogs.  That means that we can make better use of memory; one blog may
take 300M of RAM, but 1000 blogs will only take 305M.  This means that
Angerwhale will be good for hosting individual blogs like this one,
but also good for hosting community sites like <a href="http://planet.perl.org/">Planet Perl</a> and <a href="http://use.perl.org/">use.perl</a>.  I
do intend to provide a public blogging service for Perl bloggers as my
first deployment, and hopefully replace <code>use.perl</code>'s aging journal
system without destroying the excellent community features.  You'll
also get Planet Perl for free.)</p>
<p>The next part of Angerwhale will be a new web framework.  It won't be
like the other new web frameworks, though; the goal is to unify all
the Perl web frameworks and provide a true framework framework for
everyone to build on.  (The goal of the other "new" web frameworks, it
seems, is to provide fewer features under the guise of "simplicity".
Forcing users to reinvent the wheel is not simplicity, though, and I
think this idea sucks.  Perl is about TMTOWTDI, not being told that
your way is wrong and that you should go fuck yourself if you don't
like <i>my</i> way.)</p>
<p>The framework will consist of 4 completely separate parts.  The first
is the "app engine", to support things that concern the entire
application.  It knows nothing about the web, and doesn't care. (So
you can use it in non-web daemons too.) It will provide features like
timed events ("clean my sessions table every hour"), an event loop (so
that you can fork, fetch web pages, or access your database <i>without
blocking other requests</i>), logging, and debugging tools (you can embed
a <code>Stylish::REPL</code> instance and introspect your live application).</p>
<p>It will be <code>AnyEvent</code> based, so you can freely choose between <code>EV</code>,
<code>POE</code>, or <code>Event</code> in your application.  (The other parts of the
framework, like <code>Stylish::REPL</code>, <code>HTTP::Engine</code>, <code>AnyEvent::DBI</code>,
and so on, all use AnyEvent, so the framework won't make any event
loop policy decisions for you.  That way you can use your favorite
event loop, or run code that already depends on one, inside the
framework.  This provides the most flexibility and reusability, and I
like the AnyEvent sugar a lot anyway. :)</p>
<p>The next part is the HTTP helper, <code>HTTP::Engine</code>.  This is what
actually glues the app to the web.  I am currently writing an
<code>AnyEvent</code> backend for <code>HTTP::Engine</code>, so that web IO is completely
non-blocking.</p>
<p><code>HTTP::Engine</code> gives you the basic request/response capabilities, and
also provides middleware (debug screens, authentication, etc.).  It
knows how to talk to mod_perl, or be its own server, or be served with
FastCGI; so, as with Catalyst apps, this is something your application
doesn't need to worry about.  Develop with the embedded server, deploy
with FastCGI, it will all work.</p>
<p>The idea is that it will handle everything that is specific to the
web, but not specific to your application.  (If you haven't tried
<code>HTTP::Engine</code> yet, you should.  It's really easy to set up, and is a
great fit for applications that don't require a "real" framework, but
that you don't want to use CGI for.  And let's face it, you don't want
to use CGI for anything but the smallest toy apps. My
<code>App::TemplateServer</code> on CPAN uses it, so take a look.)</p>
<p>The third part of the framework is a component loader.  Current web
frameworks tend to load components "automatically", but this is not
always the most desirable approach.  Something like <code>Bread::Board</code> is
much better.  My framework will let you load components however you
want; you can do it Catalyst-style, use can use Bread::Board, or you
can just do it with some code.  Your choice.</p>
<p>At this point, you have a solid foundation for building a long-running
Perl application, you have a generic way of interacting with the web
(complete with niceties like middleware), and you have a solid way of
loading and configuring the application's components.  That leads us
to the last layer, the actual framework.</p>
<p>Basically, you can do what ever you want here.  I am planning on
making it possible to use existing Catalyst controllers in the
application, and to support Continuity.  (I have use cases where I
want both styles in my app -- Catalyst-style actions for the public
part, and Continuity actions in the administrative area.)</p>
<p>Stevan Little is currently working on a framework that is
document-based; you make objects that know how to be mutated and how
to render themselves, and the framework takes care of the rest.  This
will integrate cleanly with this framework, of course.</p>
<p>If you really don't like framework-y stuff, just use <code>Path::Router</code>
to assign function calls to URIs.  It's simple, easy to understand,
and you can dive into something more complex later, if you want to.
The best of all worlds.</p>
<p>So that's basically it -- the future of Perl web frameworks is
unification.  Users shouldn't have to commit to one way of thinking --
everything should work together.  That is my goal.</p>
<p>It's important to say that this isn't just pie on the sky -- I am
actively working on these projects (and not by myself, this is a
community project).</p>
<p>I will be talking about this stuff more throughout the year.  First at
NPW, and at YAPC::NA, YAPC::EU, and YAPC::Asia.  Hopefully by YAPC::EU
and YAPC::Asia, this will be code you can use in your own
applications!</p>
<p>Anyway, ping me on irc and let's chat!</p>


</div>
      </div>
    </content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">Angerwhale Catalyst Programming</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-03-04T14:35:26Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-03-04T14:35:26Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">Jonathan Rockway</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:urn:guid:DBD454EA-08C8-11DE-8A60-185E15E4E093</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Catalyst 5.71000</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://bricas.vox.com/library/post/catalyst-571000.html?_c=feed-atom" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">
            
                
         Like i said back in July, Catalyst 5.71000 would happen before the moose-ified 5.80 gets shipped. That day is here. Here's the basics on what's new since 5.7015:      Relatively chained actions     PathPrefix (I only mentioned that, oh, 2 years ag...    
    Read and post comments   |   
    Send to a friend 


                
            
        </summary>
    <content xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
            
                <div xmlns="http://www.w3.org/1999/xhtml" xmlns:at="http://www.sixapart.com/ns/at">
         Like i said back in July, Catalyst 5.71000 would happen before the moose-ified 5.80 gets shipped. That day is here. Here's the basics on what's new since 5.7015:      Relatively chained actions     PathPrefix (I only mentioned that, oh, 2 years ag...   <p> 
    <a href="http://bricas.vox.com/library/post/catalyst-571000.html?_c=feed-atom#comments">Read and post comments</a>   |   
    <a href="http://www.vox.com/share/6a00d09e62f541be2b0109d07dfe19000e?_c=feed-atom">Send to a friend</a> 
</p>

                </div>
            
        </div>
    </content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">catalyst</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-01-19T21:04:02Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-01-19T21:04:02Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">Brian</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:vox.com,2009-01-19:asset-6a00d09e62f541be2b0109d07dfe19000e</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Perl 5 for the Future - The Enlightened Perl Organization</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://www.dev411.com/blog/2009/01/14/perl-5-for-the-future-the-enlightened-perl-organization" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">A number of people I know through the Perl community have come together to form The Enlightened Perl Organization (EPO). The goal is to modernize Perl 5 and make it competitive with new developments in programming languages, given that it's unknown when Christmas (the delivery date for Perl 6) will arrive.

My take on this is that while other organizations focus on ongoing development of Perl 6, EPO will seek to enhance Perl 5 and take it out of "maintenance mode." Enhancing Perl 5 will hopefully bring much needed modernization to the Perl 5 core that people can use sooner rather than later. One of the most exciting developments in the Perl community, which addresses some of the core criticism of Perl 5, is Moose, an object system that modernizes Perl 5. Unlike previous efforts efforts to enhance Perl 5's object system, this one seems to have gained a lot of traction with 136 current logins on the #moose IRC channel. Moose is different enough that some have even claimed that it is not Perl; however, this is clearly not the case as Moose and non-Moose objects and be freely intermingled within Perl projects. For some information Moose, check out this article by Jon Rockway. In addition to Moose, check out KiokuDB an interface for schema-less databases like Amazon SimpleDB and CouchDB as well as more traditional DBI for RDBMs. In addition to supporting projects, ideally Perl 5's core module list can be modernized so more people will be able to take advantage of and feel comfortable recommending modern approaches to Perl development.

At the same time, I'd also like to see them tackle a few more persistent issues, the most important of which is CPAN usability. There is no doubt the Perl community and the CPAN are very compelling; however, installing CPAN dependencies is more difficult than it needs to be. Installation often requires many interactive prompts and can take a long time for applications with many dependencies. There are typically no 5 minute installs like exist for WordPress, PHPbb, and MediaWiki. Some exceptions include qpsmtpd and Catalyst using Matt Trout's cat-install script.

I welcome EPO as another organization in the Perl community to keep Perl modern and vibrant.

</summary>
    <content xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>A number of people I know through the Perl community have come together to form <a href="http://www.enlightenedperl.org/">The Enlightened Perl Organization (EPO)</a>. The goal is to modernize Perl 5 and make it competitive with new developments in programming languages, given that it's unknown when Christmas (the delivery date for Perl 6) will arrive.</p>

<p>My take on this is that while other organizations focus on ongoing development of Perl 6, EPO will seek to enhance Perl 5 and take it out of "maintenance mode." Enhancing Perl 5 will hopefully bring much needed modernization to the Perl 5 core that people can use sooner rather than later. One of the most exciting developments in the Perl community, which addresses some of the core criticism of Perl 5, is <a href="http://www.iinteractive.com/moose/">Moose</a>, an object system that modernizes Perl 5. Unlike previous efforts efforts to enhance Perl 5's object system, this one seems to have gained a lot of traction with 136 current logins on the #moose IRC channel. Moose is different enough that some have even claimed that it is not Perl; however, this is clearly not the case as Moose and non-Moose objects and be freely intermingled within Perl projects. For some information Moose, check out <a href="http://blog.jrock.us/articles/Myth:%20Moose%20is%20an%20unnecessary%20dependency.pod">this article by Jon Rockway</a>. In addition to Moose, check out <a href="http://www.iinteractive.com/kiokudb/">KiokuDB</a> an interface for schema-less databases like <a href="http://aws.amazon.com/simpledb/">Amazon SimpleDB</a> and <a href="http://couchdb.apache.org/">CouchDB</a> as well as more traditional DBI for RDBMs. In addition to supporting projects, ideally Perl 5's core module list can be modernized so more people will be able to take advantage of and feel comfortable recommending modern approaches to Perl development.</p>

<p>At the same time, I'd also like to see them tackle a few more persistent issues, the most important of which is CPAN usability. There is no doubt the Perl community and the CPAN are very compelling; however, installing CPAN dependencies is more difficult than it needs to be. Installation often requires many interactive prompts and can take a long time for applications with many dependencies. There are typically no 5 minute installs like exist for WordPress, PHPbb, and MediaWiki. Some exceptions include qpsmtpd and <a href="http://www.shadowcat.co.uk/static/cat-install">Catalyst using Matt Trout's cat-install script</a>.</p>

<p>I welcome EPO as another organization in the Perl community to keep Perl modern and vibrant.</p>

</div>
    </content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">perl</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2009-01-14T01:21:00-06:00</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2009-01-14T01:21:00-06:00</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">John Wang</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:urn:uuid:9e0b28f2-c1d0-4d1e-8689-cbaf6ac74690</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Come Work For Us</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://www.onemogin.com/blog/596-come-work-for-us" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">I work for magazines.com and we are looking to add to our team!
We’re a Perl shop, located in Franklin, Tennessee.  We sell magazine subscriptions online.  This year we’ve got a lot to do and I’m looking to add some developers to our ranks.  I’m not sure how many yet, but I can give the following details:

Telecommuters are welcome.
“New” code: Catalyst, DBIx::Class, Moose and all those things.
2009 Projects include two major “new” projects plus maintenance and refactoring in older applications.  Lots of niches to fill.  We’ll find the right one for you.
Apache, MySQL and Linux.
Conferences!  Number depends on schedule and work to be done.

We aren’t looking for a particular job level. I’m interested in juniors to seniors.  The candidates we choose will depend on the choices we have.  If you are interested then drop an email to me via cwatson at magazines dot com.
I’m really excited about our work in 2009.  I’m opening the year with two talks at the Orlando Perl Workshop and a commitment to work with the Enlightened Perl Organisation.  I’ll eventually post this opportunity on jobs.perl.org but wanted to start here.  Give me a shout!
</summary>
    <content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;I work for &lt;a href="http://www.magazines.com"&gt;magazines.com&lt;/a&gt; and we are looking to add to our team!&lt;/p&gt;
&lt;p&gt;We&amp;#8217;re a Perl shop, located in &lt;a href="http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=franklin,+tn&amp;amp;sll=37.0625,-95.677068&amp;amp;sspn=46.226656,78.134766&amp;amp;ie=UTF8&amp;amp;ll=35.958556,-86.801949&amp;amp;spn=0.185637,0.305214&amp;amp;z=12"&gt;Franklin, Tennessee&lt;/a&gt;.  We sell magazine subscriptions online.  This year we&amp;#8217;ve got a &lt;em&gt;lot&lt;/em&gt; to do and I&amp;#8217;m looking to add some developers to our ranks.  I&amp;#8217;m not sure how many yet, but I can give the following details:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Telecommuters are welcome.&lt;/b&gt;
&lt;li&gt;&amp;#8220;New&amp;#8221; code: Catalyst, DBIx::Class, Moose and all those things.&lt;/li&gt;
&lt;li&gt;2009 Projects include two major &amp;#8220;new&amp;#8221; projects plus maintenance and refactoring in older applications.  Lots of niches to fill.  We&amp;#8217;ll find the right one for you.&lt;/li&gt;
&lt;li&gt;Apache, MySQL and Linux.&lt;/li&gt;
&lt;li&gt;Conferences!  Number depends on schedule and work to be done.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We aren&amp;#8217;t looking for a &lt;em&gt;particular&lt;/em&gt; job level. I&amp;#8217;m interested in juniors to seniors.  The candidates we choose will depend on the choices we have.  If you are interested then drop an email to me via cwatson at magazines dot com.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m really excited about our work in 2009.  I&amp;#8217;m opening the year with two talks at the &lt;a href="http://perloasis.org/opw2009/"&gt;Orlando Perl Workshop&lt;/a&gt; and a commitment to work with the Enlightened Perl Organisation.  I&amp;#8217;ll eventually post this opportunity on &lt;a href="http://jobs.perl.org/"&gt;jobs.perl.org&lt;/a&gt; but wanted to start here.  Give me a shout!&lt;/p&gt;
</content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">Catalyst Code General Languages Linux Operating Systems Perl Useless Information Work</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2008-12-24T02:32:42Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2008-12-24T02:32:42Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">gphat</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:http://www.onemogin.com/blog/?p=596</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Nope, I’m Not Dead</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://www.onemogin.com/blog/589-nope-im-not-dead" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">I recently rejoined my team at magazines.com and have been pretty busy getting back into the groove there.  It’s a busy place in Q4, so side stuff has taken a back seat.  Well, that’s mostly WoW’s fault.
While I’m at it, if you are a LAMP System Administrator in Nashville (or nearby) and are looking for a great opportunity, drop an email to cwatson at magazines dot com!
On a side note, my first entry of the 2008 Catalyst Advent Calendar went up today.  Enjoy!
</summary>
    <content xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>I recently rejoined my team at <a href="http://www.magazines.com">magazines.com</a> and have been pretty busy getting back into the groove there.  It’s a busy place in Q4, so side stuff has taken a back seat.  Well, that’s mostly <a href="http://www.worldofwarcraft.com">WoW</a>’s fault.</p>
<p>While I’m at it, if you are a LAMP System Administrator in Nashville (or nearby) and are looking for a great opportunity, drop an email to cwatson at magazines dot com!</p>
<p>On a side note, my <a href="http://www.catalystframework.org/calendar/2008/3">first entry</a> of the <a href="http://www.catalystframework.org/calendar/2008/">2008 Catalyst Advent Calendar</a> went up today.  Enjoy!</p>
</div>
    </content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">Catalyst Code Useless Information Work</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2008-12-04T00:14:20Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2008-12-04T00:14:20Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">gphat</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:http://www.onemogin.com/blog/?p=589</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Orland Perl Oasis Talk: Catalyst &amp; Chained</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://jshirley.vox.com/library/post/orland-perl-oasis-talk-catalyst-chained.html?_c=feed-atom" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">
            
                
         I will be giving a talk titled Catalyst &amp; Chained: Bondage for better applications at the Orlando Perl Oasis.  Abstract: Need to build a web application and keep hearing about methods you aren't quite sure of?  Know Catalyst but don't feel you rea...    
    Read and post comments   |   
    Send to a friend 


                
            
        </summary>
    <content xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml" type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
            
                <div xmlns="http://www.w3.org/1999/xhtml" xmlns:at="http://www.sixapart.com/ns/at">
         I will be giving a talk titled Catalyst &amp; Chained: Bondage for better applications at the Orlando Perl Oasis.  Abstract: Need to build a web application and keep hearing about methods you aren't quite sure of?  Know Catalyst but don't feel you rea...   <p> 
    <a href="http://jshirley.vox.com/library/post/orland-perl-oasis-talk-catalyst-chained.html?_c=feed-atom#comments">Read and post comments</a>   |   
    <a href="http://www.vox.com/share/6a00c2252c33588fdb010981107b8d000c?_c=feed-atom">Send to a friend</a> 
</p>

                </div>
            
        </div>
    </content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">perl conferences talks catalyst</dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2008-11-26T20:24:24Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2008-11-26T20:24:24Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">J. Shirley</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:vox.com,2008-11-26:asset-6a00c2252c33588fdb010981107b8d000c</id>
  </entry>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <title xmlns="http://www.w3.org/2005/Atom">Catalyst helpers - plugins for Module::Starter?</title>
    <link xmlns="http://www.w3.org/2005/Atom" rel="alternate" href="http://perlalchemy.blogspot.com/2008/10/catalyst-helpers-plugins-for.html" type="text/html"/>
    <summary xmlns="http://www.w3.org/2005/Atom">Code generation is hard.  First of all it is hard to determine what really needs to be created - in (computing science) theory you can always uncurry the generator and use it as a library.  So you need different theory to really determine if code generation makes sense at all.  In practice many people use it - since it let's us start new projects faster (and more correctly).  This is an interesting subject deserving many more blog posts - but for now I just wanted to toss the idea that joining forces with other Perl projects facing this problem could help us improve the mess that is Catalyst helpers now.I've learned about Module::Starter plugins from Recursive development that leads nowhere.</summary>
    <content xmlns="http://www.w3.org/2005/Atom" type="text">Code generation is hard.  First of all it is hard to determine what really needs to be created - in (computing science) theory you can always &lt;a href="http://en.wikipedia.org/wiki/Currying"&gt;uncurry&lt;/a&gt; the generator and use it as a library.  So you need different theory to really determine if code generation makes sense at all.  In practice many people use it - since it let's us start new projects faster (and more correctly).  This is an interesting subject deserving many more blog posts - but for now I just wanted to toss the idea that joining forces with other Perl projects facing this problem could help us improve the mess that is Catalyst helpers now.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;I've learned about Module::Starter plugins from &lt;a href="http://www.szabgab.com/blog/2008/10/1224584435.html"&gt;Recursive development that leads nowhere&lt;/a&gt;.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img&gt;&lt;/div&gt;</content>
    <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/"></dc:subject>
    <published xmlns="http://www.w3.org/2005/Atom">2008-10-23T09:29:00Z</published>
    <updated xmlns="http://www.w3.org/2005/Atom">2008-10-23T09:29:00Z</updated>
    <author xmlns="http://www.w3.org/2005/Atom">
      <name xmlns="http://www.w3.org/2005/Atom">zby</name>
    </author>
    <id xmlns="http://www.w3.org/2005/Atom">tag:plagger.org,2006:tag:blogger.com,1999:blog-36345871.post-6666683994770811455</id>
  </entry>
</feed>
