It occurred to me today that if you look at my history as a CPAN author, you’ll see that I’ve either written or heavily participated in every popular target of re-invention on CPAN!

I started off by writing an ORM, Alzabo. Back when I released it, this was one of the very first ORMs for Perl. Amusingly, I re-invented the whole ORM concept pretty much independently. I don’t think I even heard the term until after Alzabo was released.

(Class::DBI was also released around the same time, and became much more popular.)

Of course, if you do enough database programming in an OO language, an ORM is an obvious concept to “invent”, and that probably explains why there’s so damn many of them. People “invent” them before they realize that there are dozens already out there.

I’ve also worked on a templating system, Mason. In fact, before that, I wrote a mini-templating system at Digital River, where I worked with Ken Williams. Fortunately, Ken pointed me at Mason before I could get too far into my own, which was a good thing.

Mason is also a (primitive) webapp framework, so I’ve worked on one of those too, as well as providing an odd patch or two to Catalyst and various Catalyst plugins.

Then there’s the Perl DateTime project, which was an explicit and clearly thought out wheel reinvention exercise. The existing wheels were all kind of broken, and you couldn’t easily put any two wheels on the same car, so we came up with a plan for a whole set of interchangeable wheels and assorted other parts.

Nowadays I spend a lot of time on Moose, which is one of the most recent (and by far the best) in a long series of “make Perl 5 OO better” modules.

To top off my wheel-ish history, I have a new ORM, Fey::ORM, meaning I am the creator of both one of the oldest and one of the newest ORMs on CPAN.

Truly, I am the master of wheels, both re-invention and polishing those already in existence.

Well, I thought I was getting better, but I was wrong. Last week my infection seems to have had a resurgence, and I’m not feeling well enough to travel.

Yuval Kogman has offered to teach the Moose tutorial at OSCON, so that will still go on, assuming O’Reilly agrees to the switch.

I’m still hoping to go to Italy in October. If I’m not recovered by then, I’m just going to have to get a robot body, because this meat sack is not working out so well.

A recent thread on the Mason users list reminded me of the problems I had grokking Catalyst when I first looked at it. Raymond Wan wrote “I’m skimming over the MVC part and as my system doesn’t use an SQL database, I’m wondering if Catalyst is overkill??”

Those of us who know Catalyst know that this question is based on some wrong assumptions, but it’s easy to see why Raymond has those assumptions. Look at the Catalyst tutorial. In the very first chapter, it’s already talking about databases and DBIx::Class.

It’s easy to look at this and assume that Catalyst is somehow tightly bound to DBIx::Class or SQL databases.

The problem is that the tutorial docs really need to serve two different audiences, though both audiences are Catalyst newbies.

On the one hand, you have people with relatively little web app experience. Presumably, they know some Perl, and they do a web search for “perl web application framework”. Eventually, they’ll get to Catalyst and start reading about it. For those people, being given a set of standards and a full walk through of Model and View (in addition to Controller) is very valuable. It gives them all the tools they need to get started on simple web apps without having to make too many choices.

The other audience is people who have some real web app development experience with something more primitive than Catalyst. These could be people coming from a Mason-based site without any real controllers, or people who used something like Apache::Template with mod_perl, or maybe they wrote their own controllers “by hand” using the mod_perl API.

Many of those folks will already have some experience with models. To refer back to Raymond, presumably his system already has some sort of model code, it just doesn’t use a SQL DBMS. Those people will look at the existing Catalyst tutorial and get confused. Isn’t Catalyst flexible? Then why does it look like RoR, with all my tool choices made for me?

It took me a while to realize that Catalyst, at its core, is smaller than you might think, and you can use just the pieces you like.

The very core of Catalyst is its dispatching system. Given a URI, it selects a piece of code to run. Its dispatcher is very powerful (Chained methods are great!), and with plugins like Catalyst::Action::REST, it’s even better.

Along with the dispatching system, Catalyst also provides an abstraction over the typical web app request/response cycle. The Request makes it easy to look at incoming query arguments, POST data, file uploads, and headers. The Response lets you set headers and return output to the client, whether that be HTML or a downloadable file.

Catalyst also includes engines (think “environment adapters”) for a number of common web application environments, including vanilla CGI, mod_perl, FastCGI, and more. These engines make sure that the Request/Response API works exactly the same in any environment where Catalyst can be deployed.

This is a huge win, since you can write your app without worrying about the deployment environment. If you’re writing an app for public distribution, it gives the installing users a choice of how to deploy.

These core pieces are really the only parts of Catalyst you have to use when you use Catalyst. If you don’t want dispatch and a request/response API, you don’t want Catalyst.

Catalyst (really Catalyst-Devel) also includes a fantastic single-process development server. This server can be started straight from an application’s checkout directory with one command. Even better, this dev server can be told to monitor all relevant files and restart itself when any of them change. Note that this is a proper restart, which avoids all the myriad problems that afflict Apache::Reload and its ilk, which attempt to reload modules in the same Perl interpreter.

Just these things – controllers, a request/response abstraction, deployment agnosticism, and a great dev environment – are enough to make Catalyst a great choice. Ignore everything else it does and you’ll still have improved your development process and improved your code.

Catalyst also does some other things …

It has a component system which has allowed people to release a whole host of useful plugins. If you look on CPAN, you’ll find things like sessions, powerful authentication, dumb authentication, I18N, and much more. If a plugin does what you need, it’ll save you a lot of development time.

Note that the old “Catalyst::Plugin” system is in the process of being deprecated, but the concept of pluggable components is still core to what Catalyst is. All that’s changed is the way pluggability works.

Catalyst lets you have multiple views. While many apps will just output HTML via a templating system, this flexibility is great for RESTful apps that may want to output XML, JSON, and still fall back to HTML for browsers (see my REST-ForBrowsers for some help with that).

Catalyst also has configuration file handling built-in. Personally, I avoid it, because it only works within the context of the whole “Catalyst environment”. That means it’s awkward at best to load the configuration outside of the web environment. I always make sure that application wide setting are available for things like cron jobs. This falls into a category of Catalyst features which are not best practices, but are probably useful for people writing their first web app.

Catalyst gives you hooks for models. Again, this is something I never use, but it’s another “useful for web app n00bs” feature.

There’s probably many other things I’ve left out. The point is that Catalyst provides a very powerful set of core web app tools, and that core is actually small.

Relative to a “my way or the highway” type framework (RoR and Jifty, I’m looking at you), it’s easy to port an existing application to Catalyst. In fact, using Catalyst::Controller::WrapCGI, you can wrap an existing CGI application with Catalyst, and then convert slowly over to “native” controllers.

And most importantly, you can move to Catalyst without touching your model at all! Since many applications have the bulk of their code in the models (at least, they do if you’re doing it right), this is a huge win.

Next step is to turn some of this rambling into doc patches. I think a section of the Catalyst tutorial aimed at folks coming from an “old school” web app background would be great, and would really help people like Raymond (and would’ve helped me a few years back).

So a few weeks ago I got an infection that’s quite painful to have. The infection is gone but the pain lingers on, and according to my doctor can linger for months.

I realized today that I am still exhausted from being sick, as well as being involved in the planning of three major events over the last six months or so – Frozen Perl, my AR group’s fundraising banquet, and our conference this past weekend.

To compound things, because of the pain I’m in, I can’t sleep comfortably lying down, so I’ve been sleeping a comfy chair in my living room for a few weeks. I was really dreading trying to sleep in a hotel, since they wouldn’t have comfy chairs.

So I decided to cancel the trip, even though I really didn’t want to. My wife helped me realize that I needed to.

Fortunately, Shawn Moore, Jon Rockway, and Stevan Little are helping make sure the Moose class will still happen. Some of the content will be slightly different, but I think it will still be quite good. I’ve already written a little more than half the material, and I will write some more over the next few days. Shawn and Jon also have existing talks that cover topics I wanted to cover in the class, so they will include those talks.

Overall, I think the class will work out, and I’m really thankful to Shawn, Jon, and Stevan for agreeing to jump in at the last minute. Since the class is on Sunday, I’m sure people have arranged their travel schedules specifically to be there, and I’d really be sad if there was no class for them to attend.

I’m still planning to be at OSCON (I better be recovered enough by then), and I’m still considering YAPC::Asia.

I hope everyone has a good time in Pittsburgh.

I’ve been thinking about this idea of ruthless pragmatism over the last few days. What is ruthless pragmatism? How can we actually be ruthlessly pragmatic? Do we even want to be?

Defining ruthless pragmatism is harder than you might think. The problem is that it’s easy to claim we’re being pragmatic, but I think mostly that consists of acting out our biases. If you are inclined to think that people won’t hear our (animal rights) message, you’ll probably tend towards so-called “direct action”, because you think that intimidation and property damage are the most pragmatic approach. If you think otherwise, maybe you tend towards outreach and education. Either way, it’s easy to give lip service to pragmatism.

The other problem of definition is one of scope. Anyone concerned with animal rights should also be concerned about human rights. For example, non-human animals might be best served by the forced extinction of the human species, but that doesn’t consider all animals’ rights. Similarly, we need to be careful not to sacrifice other social justice issues on the altar of animal rights.

But I think a ruthless pragmatist needs to have an even broader and longer-term view. It’s easy to push yourself to give 150% for animals all of the time, but how long can that last? If you are unhappy with your life, will you be a lifelong activist? Is it better to push as hard as possible for ten years and then stop, or should you aim for a reduced effort over fifty years? If you engage in actions that violate your own sense of justice, are you being pragmatic, or does the inevitable psychological backlash make this ineffective in the long run?

These are all hard questions. It’s easy to say things like “by any means necessary” or “we must all do things we don’t like”, but I’m not convinced that this attitude is truly pragmatic. It certainly feels pragmatic. Activists, more than most, are prone to mistake self-denial and self-abuse for pragmatism. It’s easy to look at all the suffering in the world and think that only if you are personally unhappy are you really doing all you can. But that’s a trap that leads to burnout and increased despair. If you’ve been active in animal rights for a while, you’ve probably known people who’ve left the movement, many giving up veganism or even going back to eating meat. A pragmatic movement will do its best to keep people active and living their values for their entire life.

There’s another part of ruthless pragmatism that we’re missing as activists, and that’s measurement. I’ve heard very little in the movement about concrete strategies for measuring the success of various actions. Does the ALF have a feedback loop built-in? Do they stop and evaluate every few years? Sure, they may measure their economic damage, but do they actually have a way to evaluate the impact of that damage?

But let’s not pick on the ALF. Do we at Compassionate Action for Animals do this? We do, actually, but we could do much better! Most of our metrics are not measuring the actual impact on animals. Instead, we measure things like number of attendees at events and their evaluations, number of leaflets distributed, etc. These are all interesting, but we haven’t actually established a concrete connection between these numbers and the actual impact on animals. Even worse, we don’t have any good way to figure out if we should be doing some other set of activities entirely.

Pragmatism requires more than measurement after the fact. We also need to constantly be on the lookout for new research to direct our actions. As a movement, I don’t hear much talk about the latest research in psychology, sociology, or economics. Much as it may be painful, we need to take a page from Madison Avenue and figure out the best ways to influence people (hint to the so-called abolitionists, it’s not logical argument!). More and more these days, research is showing that people’s behavior is shaped by unconscious factors they can’t even articulate. How can we take advantage of that in our movement?

So do we want to be ruthlessly pragmatic? I’ll give that a qualified “yes”. First, we need to expand the scope of our ruthlessness. Our ruthlessness must be both ethical and sustainable. Anything else just isn’t ruthless or pragmatic enough. Second, we need to work past our built-in biases and use measurement and research to make our actions as effective as possible.

I’m not trying to pick on pattrice, I promise. In fact, I thought her keynote was thoughtful and thought-provoking, and that means I actually have something to say about it.

During her keynote, pattrice stated that meat consumption is at an all time high. I can’t argue with the raw numbers. More animals are being killed for food now than ever in the past. But I’m getting a little tired of hearing this fact quoted without any context.

First, I think it’s important to realize that meat consumption has been going up for a long time. I don’t have any facts to point to (I’m lazy), but it’s reasonable to assume that meat consumption started increasing long before there was an animal rights movement. In fact, increases in meat consumption probably date back to the beginning of agriculture, when people were able to raise animals, rather than having to hunt them.

The beginning of the modern animal rights movement is generally placed some time in the 1970s. Many people say it began with the publication of Animal Liberation in 1975. The fact that meat consumption has increased since the movement began is part of a longer historical trend of more people having more money, and also the increased industrialization of meat production. So meat has gotten cheaper, and more people have more money to buy it.

Additionally, since the animal rights movement began, the worldwide human population has increased dramatically. In the US alone, our population went from 200 million in 1970 to 300 million in 2007.

We can measure the success of the animal rights movement in part by measuring the increase in meat consumption against the increase in the human population. If we really wanted to get fancy, we’d also measure it against the percentage of people living in poverty (more richer people means more meat).

Ultimately, I don’t know if we’re winning. I do think pattrice (and many others) are using the wrong metrics, and statements based on said metrics are useless at best, and harmful at worst.

If anyone out there is doing any solid work on understanding trends in meat consumption as part of larger population and wealth trends, I’d love to know about it.

Update: The first version of this entry was all mixed up with the next entry. That’s now fixed.

This past weekend’s TLOV 2009 conference is over, and I have a lot to think about. In particular, I both agreed and disagreed with much of pattrice jones’ keynote on Sunday afternoon.

Her keynote outlined an approach to animal rights based on the axiom that “animals exist”. This means that animals are creatures with desires that need to respected right now, as opposed to in some future theoretical sense. As a consequence, this requires animal activists to act with “ruthless pragmatism”, which may mean doing things that make us ethically uncomfortable.

I (mostly) agree.

She said that simply getting people to go vegan is not enough. She stated that in order to win we have to both reduce demand and raise the costs of doing (animal abuse) business.

I agree with this as well, but with some caveats.

Pattrice praised both the ALF as well as welfare legistation like Prop 2. It’s true, both do raise the costs of doing business. The welfare legislation also has a real impact on actual animals, and so is worthy in and of itself (as long as there’s not something even more useful we could be doing).

But let’s tackle the ALF. Is the ALF ruthlessly pragmatic? I don’t think so. In fact, the ALF is one of the most idealistic “organizations” I know of. Certainly, they’re not metrics-based, methodical, or any of the other things I associate with pragmatism.

Pattrice says that the ALF has cost animal abuse industries millions of dollars through their vandalism and animal releases over the years of their existence. So how much is “millions”? In 2002, The FBI testified before Congress that the ALF and ELF combined had caused $43 million in damage since 1996. From my reading online, it seems like ELF is more damaging in their activities, but let’s be generous and split it. That means that the ALF is doing approximately $20 million in damage (in the US) every five years.

The first question, then, is does this damage raise the cost of doing business? Second, is this the most effective thing that these activists could be doing?

I think the first question is relatively easy to answer. In the US alone in 2006, the mink “crop” sold for approximately $136 million at auction. Looking back at previous years, wholesale mink pelt values at auction were more than $1 billion from 1998-2007.

So we have an industry making $1 billion in 10 years (in the US alone) at wholesale! The retail amounts are even more staggering. Retail fur sales were $1.34 billion in 2007 alone.

So given those numbers, is it reasonable to think that the ALF’s generously estimated $40 million in the same time period had an impact on the fur industry? I don’t think so. Even if all $40 million in damage had been taken just by mink “farmers” (which it wasn’t), that’s less than 5% of their income. Unless their margins are ridiculously low, it’s hard to imagine this being a major problem.

Even if this caused a 5% increase in retail costs, fur coats are a luxury good. Luxury goods have a lot of price elasticity, and a 5% increase in price may have a 0% impact on sales! And given the 10x markup from wholesale to retail, there’s clearly room for retailers to absorb a 5% increase in the costs paid to wholesalers.

This might all sounds like I’m saying that the ALF just needs to get out there and do a lot more damage. At some amount of damage, they would be able to have a serious impact on prices, and this would eventually decrease sales, which in turn would decrease production.

The problem with this approach is that we haven’t yet looked at the costs to the animal rights movement. I’d love to argue that the ALF’s actions are detrimental to the movement as a whole. They make us look bad, and make it hard to get people to listen to us. But that’s a somewhat nebulous argument.

A more solid argument is that the costs to the ALF activists themselves are very, very high. Any activist who is involved in a significantly damaging action wil become a high-priority target for law enforcement. The most likely outcome is that they will be caught, turned into witnesses against their cohorts, and/or put in jail for long periods of time. Either way, they are no longer able to be activists for a significant period of time, and they are certainly not able to repeat their ALF actions on a regular basis.

So the price of “success” for an ALFer is to stop being an activist for a non-trivial amount of time. Of course, this “success” also imposes a cost on the larger movement, as well-meaning supporters spend money and time on the ALFer’s legal defense and jail support.

The animal rights movement cannot compete with animal ag when it comes to money. In their 2007 fiscal year, HSUS had approximately $100 million in income. HSUS is by far the biggest 501c3 working on animal rights in the US, and arguably only some of their money goes to “animal rights” work (I’m not knocking HSUS for that, BTW, I think they’re great).

PETA, which is probably the next biggest organization, brought in about $30 million.

That’s pocket change compared to the combined financial resources of the animal abuse industries. Mink wholesale alone is equivalent to the income of the two top AR charities in the US. The fur industry is miniscule compared to farmed animals. In 2007, beef producers alone brought in $50 billion wholesale.

That’s a lot of big numbers, and it seems overwhelming. How can we possibly win? Well, we need to be ruthlessly pragmatic. I think that strategic nonviolence is the ruthlessly pragmatic philosophy that shows us the way to victory.

Strategic nonviolence analyzes the disparity in power between us and our opponents, and shows us that we do have one big advantage. We are on the side of justice, and our cause is morally persuasive. Animals do deserve equal consideration, and they are being horribly tortured by humans. We can use this morally persuasive argument to convince members of the public to join our cause and support us.

But we cannot fight toe-to-toe with money or violence. Our opponents can outspend and outfight us quite easily. We cannot engage them on the battlegrounds where they are strongest.

We will not win unless our movement grows quite significantly. How will we know it’s grown big enough? Instead of covert releases of animals at night, 1,000 of us will march to a factory farm and liberate animal in broad daylight, unopposed. 500 of us will stand arm-in-arm blocking a slaughterhouse entry, and we’ll do it every day for a month. When we do these things, the public at large will praise our bravery and commitment to equal consideration for all beings.

But we’re not there yet.

After ranting about dependencies, I started thinking (which is not the same as ranting by any means!).

Other systems have long dependency chains, but people don’t complain. Specifically, I’m thinking of Debian, which has great tools for tracking and installing package dependencies.

I used the cool debtree tool to create a dependency graph for gimp. Check this monstrosity out!

That’s a lot of dependencies! But it isn’t considered a problem, and I don’t think you’ll find anyone out there complaining that gimp’s dependency chain is “too long”.

The difference is that debian packages always install cleanly. Install failures are rare, and are fixed very quickly.

By contrast, modules installed via the CPAN shell fail pretty often. This is a case of our own culture biting us in the ass. Debian packages do not run any tests on install. The package maintainers are just responsible for making sure that the package installs cleanly. If the package has bugs, the maintainer fixes them (or gets upstream to fix them) and makes a new package. In most cases, there probably isn’t even a test suite for the maintainer to run.

Perl has a great culture of testing. We expect all modules uploaded to CPAN to come with a test suite, and we expect modules to run their tests on install and to pass. I love that we have such high standards, but these standards are not without problems. When a module fails its tests, the person doing the install isn’t in a good position to handle it. In many cases, they could probably force the install and use the module, but how could they know that?

I’m not sure what the solution is. One possibility is for module authors to cut back on the number of tests that they run on install. We could start moving most of the tests to an “authors only” test directory. That seems kind of sad though.

Maybe there’s also an education component. We could tell people that it’s ok to force an install of a dependency, as long as the module they want to install passes its own tests. For example, if I’m installing Catalyst, I can probably live with a failure in the Data::Dump test suite, as long as Catalyst works.

Maybe the CPAN shell could have a mode where it simply ignored dependency test failures, but delayed really installing them until checking that the originally requested module passes its tests with said dependencies.

This solution accounts for the reality that everything has bugs. The Catalyst authors can work around bugs in their dependency chain, and all you as an end-user really care about is that you can use Catalyst as advertised.

I’m not sure what the best solution is, but I do know that the solution is not to demand that module authors reduce their dependencies “on principle”. Encouraging wheel reinvention reduces code quality, even though it could give the appearance of less failure. This would just move failure from CPAN install time to “using the module full of reinvented crap” time.

Dear whiners-about-dependencies,

Please stop whining.

Recently, there was a thread on Perlmonks which included the quote, “the dependency chain on Moose and MooseX is *long*.”

What is “long” here? Moose really doesn’t have that many dependencies. Also, conflating Moose with a bunch of Moose extensions is just weird.

Chris Prather then wrote a blog post explaining why Moose has each dependency. That was nice of him, but I’m not sure addressing the whiners like this is worthwhile. Moose’s dependencies need no justification. We Moose authors thought we needed them, so we used them. End of story.

I really don’t understand why people complain about dependencies. CPAN is what makes Perl great. It certainly isn’t the Perl 5 language itself, which is getting a bit long in the tooth. Without Moose, Catalyst, DateTime, DBIC, etc. how interesting would Perl 5 be compared to its numerous competitors? If you want a brilliant language where you can write everything from scratch, I suggest Haskell.

If you’re going to use Perl, you need to figure out how you will handle dependencies for your applications. There are a lot of options for managing them, including:

  • Writing everything from scratch instead.
  • Copying modules wholesale into your source tree.
  • Copying tarballs into your source tree, and installing them as part of your build process.
  • Using/making packages for your system of each dependency.
  • Maintaining a local CPAN and installing from it.
  • Installing things from CPAN directly and hoping nothing breaks.
  • Some combination of the above.

These are all possible solutions (though the first is for idiots). Whining to module authors that they have “too many” dependencies is not a solution.

As an aside, at what point would the whiners stop whining? If Moose had half as many deps, would the whining end? I doubt it.

I will offer one sop to the whiners. If you as a module author are depending on a module, I hope you’re willing to help maintain that dependency. That means passing on bug reports (people will report a dependency’s bugs to you), writing patches, and generally helping keep your dependency chain installable.

The Moose docs grant is finished, so I’m going to review what exactly was accomplished, and how it differed from the original grant proposal. I’ll take each section of the original proposal one at a time.

Write a set of Moose::Intro docs

I ended up calling this documentation Moose::Manual instead, but what was produced is pretty similar to the original plan.

The original proposal called for the following sections:

  • Moose::Intro::Attributes
  • Moose::Intro::Subclassing
  • Moose::Intro::MethodModifiers
  • Moose::Intro::MooseObject
  • Moose::Intro::Roles
  • Moose::Intro::Types
  • Moose::Intro::Introspection
  • Moose::Intro::MooseX

The end result produced the following:

  • Moose::Manual::Concepts

    This is just a reworking of the Moose::Intro documentation I had written prior to the grant. It focuses on concepts without including much code.

  • Moose::Manual::Classes

    This includes the proposed Subclassing documentation, as well as providing a general intro to Moose.

  • Moose::Manual::Attributes

    This is pretty much as I imagined.

  • Moose::Manual::Delegation

    The Attributes documentation is already quite huge, so it made sense to separate a chunk out.

  • Moose::Manual::Construction

    This is the proposed MooseObject page with a better name.

  • Moose::Manual::MethodModifiers

    More or less identical to the proposal.

  • Moose::Manual::Roles

    More or less identical to the proposal.

  • Moose::Manual::Types

    More or less identical to the proposal.

  • Moose::Manual::MOP

    This is the proposed Introspection page renamed.

  • Moose::Manual::MooseX

    More or less identical to the proposal.

  • Moose::Manual::BestPractices

    This is a collection of tips I came up with while writing the rest of the manual, and it also includes recommendations that were in Moose::Cookbook::Style, which existed prior to the grant.

  • Moose::Manual::Contributing and Moose::Manual::Delta

    Stevan Little added these pages later.

Revise all of the existing cookbook recipes for clarity and simplicity

Yep, did that.

Write the recipes marked as TODO

The original proposal called for:

  • Moose::Cookbook::Basics::Recipe8 – Managing complex relations with trigger

    I ended up putting a trigger example into Recipe 3 instead. Recipe 8 remains unwritten, and probably needs a new topic.

  • Moose::Cookbook::Basics::Recipe11 – BUILD and BUILDARGS

    I wrote this.

  • Moose::Cookbook::Roles::Recipe3 – Runtime Role Composition

    I wrote this too.

  • Moose::Cookbook::Meta::Recipe6 – Hooking into the immutabilization system

    This recipe did not get written at all. The core team realized that the immutabilization system is too nasty to document as-is. For Meta Recipe 6, I showed a Meta Method class that enforces method privacy.

  • Moose::Cookbook::Meta::Recipe7 – Custom meta-instances

    I wrote this.

I also ended up writing a new recipe, Basics Recipe 12, which shows how to subclass a non-Moose parent using Moose.

Complete API docs for all Moose and Class::MOP classes

While working on this, I realized that some of the more internalish classes had really weird APIs that should not be documented. Therefore, a few classes are still entirely undocumented. In many cases, I was able to rename, deprecate, and refactor to a point where we had a reasonably sane public API to document.

So the upshot is that while not every class is fully documented, everything that should be documented is documented, for now.

What next?

Doing all this documentation work definitely highlighted some areas of the code that need changing. There are further refactorings to come, especially for the pieces that were deemed to gross to document at all. That includes immutabilization, some aspects of the type system, and some other areas.

I’d like to thank the Perl Foundation again for sponsoring this work. The grant was motivational for me, because this was a huge amount of work. I might have done some of it over time, but I doubt I would have done all or done it nearly as quickly without the grant.

I hope people out there in Perl-land find the new documentation useful. If you have feedback, you can find us on IRC at irc://, email the Moose list, or file a ticket in the appropriate queue.