March 2010 Archives

Perl 4, Back Where It Belongs


The most significant feature added to Perl 5 (released on 17 October 1994) is the module system. No longer did Perl programmers have to manage a series of .pl files mishmashed together into a library system. That change—organizing code into reusable, composable libraries—enabled the growth of the CPAN and almost every good thing which has contributed to the Perl Renaissance.

If you look in the source tree for Perl 5.10.1 (the latest stable release of Perl 5) you'll see a slew of long-forgotten .pl files which shipped with Perl 4. They've been in the core for the past fifteen and a half years, lingering mostly untouched, long superseded by other core libraries and much better distributions on the CPAN.

Given that the Perl testing revolution didn't begin until late 2001, how do you know the old code works? "I don't have to modify it!" isn't a satisfying answer. No one wants to modify it, as shown by the fact that no one has modified it in years.

This code likely won't be in Perl 5.14 (I originally wrote 5.12, but that was obviously false, as Jesse Vincent mentioned). It has a new life on the CPAN as Perl4::CoreLibs, where it can grow or fester, where people can maintain it if they want or ignore it if they don't. (You can predict my prediction.)

Perl 5.12 includes other deprecations, including some core modules spun out to the CPAN where their maintenance burden will no longer affect the core. In Perl 5.12, using them within the core gives deprecation warnings. Installing them from the CPAN does not produce those warnings. (Naturally this has been the point of some contention, though I suspect that anyone who's been writing Perl since at least 1994 knows at least one text processing language to use to update code for the latest version of Perl 5.)

If you need these deprecated modules, install Task::Deprecations::5_12 from the CPAN. (The indexer will catch up with the upload soon; it's not there at the time of writing.)

If you distribute Perl 5, consider whether you want to bundle this module with your installation, or whether your support system should notify your users about this distribution.

If you're upset about this change, if you make heavy use of this code, consider volunteering to support it on the CPAN. Meanwhile, the core gets a little slimmer, a little less crufty, and a little bit easier to maintain. I forgive you for thinking that this helps to contribute to Perl 5.12 coming out less than a year after Perl 5.10.1, because I agree.

Credit to Toolchain Developers

I'm writing an article on testing Perl 5.12.0 RC 1 for Perl Pub, and my life is much easier thanks to a handful of projects and developers. Thank you to:

  • local::lib, for supporting per-project module installation directories. I have the system Perl, Perl 5.10.1, and now Perl 5.12.0 RC 1 installed on this test server, and they don't interfere with each other. That's handy!
  • CPAN::SQLite, for making the CPAN installation process easier. Using a SQLite index is faster and more frugal with memory, especially when I have a pile of distributions to install to test with the software I want to test.
  • Module::Install, even though I gripe about the software frequently and had to work around a confusing bootstrapping issue, it's worked well since that point to install the software I care about for the project.
  • Parallel building and testing for Perl 5 itself, as it sped up the installation and testing process for the RC. (Of course, I went to lunch during that phase, but still....)
  • The new CPAN configuration system, which didn't require me to answer a lot of questions to configure a CPAN mirror and installation system.

I'm definitely doing something more complicated than the default installation of Perl 5, but my input in the process has been to fix things that definitely needed human intervention, not to babysit the process to make decisions where the defaults were fine. This is a definite improvement over last time I had to manage several parallel installations of different Perl 5 versions.

Thanks to everyone who's contributed to these projects.

Update: Chris Prather pointed out App::perlbrew, which would have made my life easier a day ago. See his Brewing Up a Storm for more information.

I'll Get the MOP....


I just completed a section on code generation in the Modern Perl book draft. Per an interesting coincidence, Moose and Class::MOP reached 1.0 on the same day.

What's the coincidence? The final subsection of Code Generation discusses the use of Class::MOP for metaprogramming.

It's simple to explain code generation and metaprogramming in terms of string eval; everyone who knows how to declare a class in Perl can figure out string quoting issues and the particular timing of BEGIN blocks and visibility and implicit closures when writing:

eval <<END_CLASS;
package $class;

use parent '$parent';

sub new      { ... }
sub get_name { ... }
sub set_name { ... }

... versus:

package My::Awesome::Subclass;

use parent 'My::Awesome::Parent';

sub new      { ... }
sub get_name { ... }
sub set_name { ... }

... but you end up having to deal with all of those issues, plus the drawbacks of string eval (it's slower than regular declaration, you don't get syntax highlighting or other IDE tools, it may leak memory in some versions of Perl 5, quoting can be a pain, parameterization is an exercise in templating systems rather than OO design, and there's no introspection or mechanism to modify the code after you've run it through eval).

You also don't get guarantees that you've written your code correctly; you might have left out an important method or an important declaration, or you may manipulate @ISA in a messy or unfortunate way, or you may step all over an existing class elsewhere, or....

It's important to have the safety valve of string eval, at least so that experienced programmers can escape from the cozy confines of what the language itself has provided if they're doing brilliant things or if they're doing dirty things and have made the sufficient determination that the risk of getting caught for cheating is worth the value of getting things done quickly.

Yet Class::MOP for all of its perceived metacircular brain-twisting confusion (and there's really only one secret to learn to untwist all of that perceived complexity, unless you want to implement or bootstrap the system) gives you all of that power and more, and all of the missing correctness, and all of the syntax highlighting, and all of the "Hey, this is just Perl I don't have to quote or worry about timing or anything wild!" if you learn that one little secret: you're only manipulating objects.

Yes, the perceived syntactic weight of creating a class with Class::MOP is higher than eval "package Foo; \@ISA = 'Bar';";, but you get introspection. You get interoperability. You get the benefit of a suite of thousands of tests and hundreds of real-world modules on the public CPAN alone ensuring that the system works. Just as Moose makes the right designs easy to choose, so too does using a formalized mechanism for metaprogramming make metaprogramming safer and easier.

(As well, anything which hides some of the gory details of Perl 5 implementation behind a nicer syntax than what Perl 5 provides in this area is an improvement on those terms alone.)

In Praise of Forking

| 1 Comment

If we are to write ever better software, we must relentlessly remove barriers to collaboration. The gitPAN is important for that reason.

When I worked on Perl Hacks in 2005, I needed a way to show off the "stuff a code reference in @INC" feature without making an obviously silly and contrived example. I chose the very real problem of wanting to know which piece of code loaded which module. This is handy for figuring out dependencies in a program, especially when you want to trim memory usage or reduce complexity.

The resulting code became Devel::TraceUse.

Perl 5's code-loading semantics aren't entirely simple nor straightforward, and the introspection capabilities of D::TU need to reflect that. The module had some bugs and corner cases, and it didn't support some uses I never considered.

Thanks to Schwern and gitPAN, Philippe "BooK" Bruhat forked Devel::TraceUse on Github to fix bugs and add features. The new version should be on CPAN shortly.

All I had to do as a maintainer was look over his changes, read the test cases, and give him co-maintainer status on the CPAN. If I wanted to fix a typo in the documentation or make a very, very quick change, all I had to do was fork his own copy, make a change, and send a pull request -- all from the browser window.

It helps that I've known BooK virtually for years and I trust his code and judgment. Yet it also helps that we can take advantage of software and services that make forking a positive act, as something lightweight and temporary and creative which we intend to merge again soon.

Sharing code on the CPAN is good, very good. So is tracking bugs and attaching patches. Yet stepping slightly beyond that to make our distribution system into a repository where we encourage modification and experimentation (always with an eye toward merging) is even better.

The strong sense of community standards in Perl and the CPAN offers many benefits. The uniformity of conventions suggests that all of the code I'm likely to use has decent documentation, a test suite, a project page on the CPAN, dependency tracking, and a very reasonable chance of installing correctly (or at least strong community pressure to figure out why it doesn't and to fix it).

I know that when I write about Text::AutoFormat, to choose a random module name I hadn't thought of until halfway through this sentence, I can link to and you can click through to read its documentation and a synopsis of its purpose and example code will be right there. That's valuable. That's useful.

I wouldn't trade those loose standards for anything.

Even so, community standards—even ad hoc customs and conventions—are not free.

Uploading to the CPAN means understanding how to build a distribution. Some people use h2xs. Some people use Module::Starter. I've grown enamored of Dist::Zilla (and see rjbs's Managing Distributions with Dist::Zilla for good advice on how to migrate to Dzil). You get to decide whether you use ExtUtils::MakeMaker or Module::Build or Module::Install. You get to learn all about CPANTS and and META.yml.

You ask for a PAUSE account and understand what that means.

You wait nervously for a group of Perl superheroes to judge you worthy and acknowledge that that silly little idea you had is worthy to go into the mythical powerful CPAN... and it happens and you wait for other Perl gurus to critique and criticize you or other normal Perl programmers to send you patches or test failure reports or.....

All of this only happens if you go through the work of learning that you have to learn all of this and if you decide that the nervousness is worth it. (It is.) As a reward, if you keep with it, you'll discover that all of these conventions are merely conventions, that you can upload almost anything to the CPAN that isn't malicious and it'll stick around, and that the real conventions, at their inescapable core, are few.

You don't have to take a side in the CPAN toolchain argument, or even know that it exists. You don't have to stick with the standard approach to documenting your code, or writing your tests, or marking your dependencies. You don't have to follow advice about namespaces and top-level namespaces and namespace registration.

You should, but none of that is essential. (You learn that from experience, not the documentation.) It's not essential, but you still have to crawl up that learning curve to the point of minimal productivity. Good Perl programmers have automated away a lot of that complexity, but not the complexity of the initial understanding.

There's no single good default tool which lets you create a module for the CPAN without worrying about some of this complexity. Maybe it's not possible to remove all of that complexity. Maybe it shouldn't be. Yet I wonder: if it's possible to create a minimal CPAN client that almost always does the right thing without configuration, is it possible to create a tool to create distributions without configuration?

You don't have to use this tool to create distributions you upload to the CPAN, of course. Yet if the best way to manage modern Perl 5 code is with the tools of the CPAN ecosystem (and it is), we should make it easier to manage DarkPAN code in the same way. (We call it DarkPAN for a reason.)

What if we could point novices to a single utility with minimal configuration which helped them build distributions with dependency tracking, documentation, testability, installability, indexability, and everything necessary to go to the CPAN or their local CPAN mirrors? What if these defaults fit the unwritten community standards in such a way that doing the right thing is much easier than not doing it—so easy that they don't even have to read about the various standards and their evolution and controversies?

People will put up with a lot if doing the necessary thing is easy. How can we encourage that?

Tests are Code Too!


Of all of the frustrating debates in software development, bickering over the value of automated testing confuses me the most. I can understand why people who've never tried pair programming seriously have doubts about it. I can even understand why people who know nothing about programming or construction think that designing a building is like designing software.

I don't understand programmers who think automated testing isn't all that useful because tests can be difficult to maintain.

Perl's testing culture had its renaissance when several of us realized that people saw testing as confusing black magic. (No joke; the "copy and paste this header into all of your test files!" generated by h2xs in used to say "black magic here" before four lines of gobbledegook.)

The nice thing about a renaissance is that you can clear away confusing, magical thinking and replace it with bright, understandable foundations for grander, more elegant, more powerful, and futureful thought.

This occurred on two levels. First, the parallel development of Test::Simple and Test::More made two libraries that were almost trivially easy to understand. Writing good tests requires skill and experience, but writing tests at all requires two minutes of reading and experimenting. The path to mastery begins not with copying and pasting black magic gobbledegook that explicitly warns you off of understanding it but by saying what you mean to say.

Another part of that was good initial design of what would become TAP way back in 1987, as well as other parts of the toolchain, but removing the initial barrier to starting was a huge improvement.

The other foot of the renaissance was Test::Builder. You can start with Test::More and use it productively... but if you're not careful, you'll end up with long, procedural test files with a lot of duplication.

Test::Builder exists solely to remove duplication. It's a foundational library for the abstraction of tests and test structures. You can see this in Testing with Test::Class. You don't necessarily have to write your own testing modules to take advantage of this possibility; the CPAN has hundreds of Test::* modules for your own use.

That's what modern Perl programmers do. We solve problems, then we make the solutions available. We'd never have achieved this for our tests if we hadn't realized the simple, fundamental fact of automated tests: they're just code. All of the good habits you have for managing code apply to managing tests.

That includes choosing the proper libraries and abstractions.

Why Modules and Plumbing

Sawyer X suggested that CPAN authors write modules due to Perl's sysadmin heritage, and Steven Haryanto responded that CPAN authors write modules because modularity is a huge design goal.

I agree in part and disagree in part. Perl's sysadmin heritage does influence design decisions, and modularity is an important feature of modern Perl development... but there's an easier, simpler, more fundamental reason why the largest repository of Perl code in the known world is primarily modules and not applications.

CPAN's design encourages the development and use of reusable modules.

By categorizing code by modules, by maintaining dependency lists between modules, by resolving dependencies automatically on successful installation, CPAN has ensured that the primary unit of code sharing in the Perl community is the module. This is not solely a fundamental design feature of CPAN itself—it's the result of a design principle of Perl 5.

The active language design principle is to allow people to make their own lexical changes that do not interfere with other lexical changes from other people, and to use those changes to improve the language in terms of its intrinsic features or its ability to work with the external world. (Many of my criticisms of and suggestions for Perl and the CPAN occur in places where this lexical extension isn't as lexical or as extensible as it could be.)

In other words, the Perl 5 module system had a goal of enabling things like Moose as much as it allowed DBI. The points of collaboration between programmers, especially for the types of software for which Perl 5 is most suitable, are reusable components. You want to read data from an LDAP server. You want to improve exception handling. You want to produce pretty charts.

It's not that Perl programmers don't write useful, usable applications all the time. We do. Sometimes we share them with other people. Yet the specific software for my business turns marked-up text into camera-ready proofs to print books. I'm happy to collaborate on a markup system, or a templating system, or a framework system for writing command-line applications which tie together a few modules into a pipeline, but the specifics of how I work aren't interesting to most other programmers or businesses.

I think that's a fundamental facet of Unix culture. We collaborate on low-level tools and utilities. We tie them together into specific, custom applications. That's no reason not to produce and distribute and collaborate at the application as well, but it's a reason why we collaborate at lower levels instead.

Learning to Fail to Learn


I've been writing about Moose in the Modern Perl book draft recently. Moose is clearly the right way to teach object orientation in the context of Perl 5, and I've enjoyed how Moose makes doing the right thing easy.

Yesterday I explained inheritance in the context of Moose and Perl 5 OO.

I'd already explained Perl roles. If I didn't have to acknowledge that people reading the book will eventually run across legacy code, I could happily gloss over inheritance as an idea that turns out to be much less useful than it first appears. I suspect that inheritance seems great to OO novices because it's spectacular and interesting: code appears seemingly for free out of nowhere! That's easy to understand, while the subtle utility of polymorphism and parametric polymorphism require you to have struggled with the problems they solve so you understand their value.

Would so many of us appreciate Moose if we hadn't wasted so much time doing things the hard way?

I spend a lot of time thinking about how to teach people to appreciate and to understand modern Perl in ways that do not lead them down the dark alleys and bumpy roads where I had to learn to program the hard way. I'm very stubborn, and I'm perfectly comfortable taking apart something to figure out how it works. (The people who fix bugs in your favorite programming languages likely share this trait.)

I don't believe that attribute is a necessary precondition for learning to program well.

However, I do wonder if it's more difficult to understand the value of a non-obvious system until you realize the drawbacks of the system you do understand. I've seen novices insist that they absolutely must use symbolic references instead of hashes, or that manual iteration instead of list transformation is so much easier, or what have you that I wonder about the diactic value of trying to show people the best general approach as I understand it now first, then mentioning other ways that aren't as good.

Consider an example. I know better ways to write Test::Builder because I've implemented it three times now, in Perl 5, Perl 6, and PIR. I like to think I'd have listened if someone suggested infelicities in its original design, but only the experience of implementing and using it helped me to understand what it really needed to do.

I wonder. Is it possible to teach Perl 5 in such a way that novices don't have to suffer all of the miscues that the rest of us have in the past decade? If so, how do I do that? (If not, what does that imply about new adoption of Perl 5 and adoption of Perl 6 in general?)

Maybe I'm conflating learning a language with learning how to design programs—but how do you separate the two when your goal is merely to teach people how to solve problems?

What CPAN Doesn't Do


Configuration-Free CPAN Installations and What's Wrong with Module::Install both hinted at a fundamental difficulty in managing software from the CPAN. Enough teasing.

The fundamental assumption of the CPAN that makes managing software through CPAN clients difficult is that newer software can always replace older software.

That's not the CPAN's problem, not really. Perl 5 has this version number problem too, and it's the source of much of the backwards compatibility troubles in the Perl 5 world.

On the CPAN, no one agrees on what version numbers mean. No one agrees on backwards compatibility concerns. No one agrees about what makes one release "stable" and another release "testing" or what you can change in an API.

I'm not sure it's the job of CPAN or the CPAN maintainers to try to solve this problem. The lack of rules and ceremony over the function of uploaded code and the loose agreement on the form of uploaded code have allowed CPAN to thrive where other languages with their own packaging and distribution systems have fragmented into incompatible, warring fiefdoms.

Even still, fighting over whether Module::Build is of the devil because (insert silly reason here) or complaining that Module::Install is a stupid patch over a pile of nasty, almost unsupported hacks misses the real point. The best possible improvement in the Perl 5/CPAN ecosystem is to know which versions of which distributions work together, and for end users to be able to download a known-working graph of their desired distribution and its dependencies.

In other words, the big problem isn't that Module::Install has a nicer interface (arguable) or ExtUtils::MakeMaker is a horrific pile of barely-working hacks that shouldn't have survived into the 21st century (indisputable). The problem is the integration of separate components managed by separate maintainers with wildly disparate ideas of the semantics of change over indeterminate periods of time.

At any single given point in time, any given CPAN distribution should work correctly with its currently available upstream dependencies. With the current system, we cannot guarantee that perturbation in those dependency graphs will percolate to users at any point in the future.

In my mind, arguing over whether an improvement to the CPAN ecosystem can take over for every use case of the current tools is stupid and wrong (or, more charitably, a silly distraction). Improving the user and developer experiences of the current tools and the current system is good, but the real improvements in the system will not occur at the interface level.

(Of course, the problem with Adam's point of view is that requiring any credible replacement to handle every possible failure case before stamping it with an imprimatur is that "better" is not an all or nothing concern. I have no illusion that it's possible to fix the Perl 5 versioning scheme for every case. If we can fix it for 90% of cases, surely that's a reasonable improvement.)

Module::Install exists because installing CPAN distributions is not always perfectly easy.

Unfortunately, it didn't help—at least, not entirely. According to the completely unscientific process by which I install CPAN distributions, Module::Install accounts for a greater amount of pain than it should, at least according to its frequency of use. (Again, this is completely unscientific. I could guess that half of the CPAN client sessions which encounter Module::Install require me to fix things manually, but it's probably closer to 20%. It's more memorable because of my severe dislike for M::I prompting to install dependencies during configuration time.)

M::I addresses a real bootstrapping problem. I want to be able to use libraries during configuration, building, testing, and installation. I don't know which versions of those libraries you have available. Bundling known-good versions of those libraries with the distribution itself solves part of that problem...

... except when it doesn't. If I were to use M::I, I would have to re-release all of my distributions for every new release of every bundled library, at least if they contain important bug fixes for the various platforms about which I care. The cheap perfume of static linking leaves its musk heavy in the air.

It's easy to fall into the trap of a false dilemma. "You fool!" you prepare to comment below. "It's either that or the chaos of trying to make do with whatever version of those dependencies users may or may not have installed on their systems!" You're right; those are two possibilities. They're not the only two possibilities.

Part of the real problem is that bootstrapping during configuration is much too late. By the time you're running the configuration system, you're already running the configuration system. If your version of the configuration system is too old or too new, you have a problem. Bail out? Revert? Upgrade? There's no good heuristic for determining this. (The CPAN itself has an opinion. That's part of the problem.)

M::I hackers do deserve credit for helping to develop the META.yml standard. (I think M::I is the wrong approach, but I intend no slight toward its users, advocates, and developers. Invention requires the courage to get things wrong sometimes, even as it requires the courage to abandon false leads.) The META.yml specification is a big step in the right direction. If most CPAN modules have static requirements and follow a standard set of conventions, there's little or no configuration necessary. A sufficiently smart CPAN client can perform the appropriate configuration without running code from the distribution itself.

You can't avoid that in all cases; distributions with XS components, for example, need to probe system information. Good luck writing a sufficiently smart CPAN client and getting the community to agree on specific standards that let you find OpenGL headers in a cross-platform fashion, for example. Yet if 80% of CPAN distributions can get by with static, upload-time configuration, a lot of complexity of installation can go away.

Yes, that would make Module::Build and ExtUtils::MakeMaker unnecessary for (probably) most CPAN distributions, at least at the point of configuration, building, and installation. (I'm a recent fan of Dist::Zilla for automating away tedium on behalf of distribution maintainers; there's less need for Module::Install in such a world. If I never write another Build.PL again, so much the better.)

That helps, but the real problem with CPAN installations is that the CPAN itself is merely an uploading, indexing, and mirroring system. Projects such as META.yml attempt to add (and extract) meaning from the system, but they cannot work around one fundamental design feature of the CPAN. That limitation is the source of most woes for end users.

Clever readers (or experienced CPAN users) have already identified this limitation. I'll reveal it in the next installment.

The 99% Rule


David Golden praised Tatsuhiko Miyagawa's excellent new cpanminus CPAN client in The power of not being all things to all people. You should consider using cpanminus.

Don't overlook something else insightful that David wrote:

It's a lot of work to be all things to all people and I keep wondering whether making things simpler and better for 99% of people would be a better choice.

The only reliable way I've ever seen to "make the easy things easy and the hard things possible" is to make the easy things the default without preventing customization of the hard things. That's a design principle for languages, APIs, and tools.

Figure out what's most common (though not necessarily what people think they want, but what they need). Optimize for that. Consider what they might need and don't prevent it.

That's not easy, and what people need will change over time, but if you want to solve problems well, you have to solve the right problems.

What's Wrong with Module::Install

| 1 Comment

I've never liked ExtUtils::MakeMaker. I've liked Module::Build from the beginning. I've never, ever liked Module::Install, even though Ingy sat in my living room and hacked on what would eventually become M::I way back several years ago.

I don't believe people who use Module::Install should be shot on sight, but I do believe that Module::Install has set the usability of the CPAN back by several years.

Ingy did identify a real problem: there's too much code strewn about the configuration and build systems of the CPAN and not enough code shared. When he found himself writing something complicated to configure, compile, and install a new distribution, he'd crib code from someone like Tim Bunce or Graham Barr or Nick Ing-Simmons. In other words, to make the CPAN—perhaps the world's largest repository of redistributable and sharable library code—work, he had to copy and paste code.

M::I did get that right; turning the configuration and build system into reusable, redistributable libraries also available from the CPAN helped reduce the amount of boilerplate code and the amount of copy and paste code in configuration systems. The people behind M::I have also helped push for better configuration of CPAN clients and better tracking of dependencies and versions and types of dependencies (optional, compilation, bundling, testing, et cetera). The CPAN ecosystem is better off for that work, even though M::I itself isn't the answer.

One of M::I's biggest failings, of course, is that it prolongs the lifespan of EU::MM. Unfortunately, I think Ingy missed the big problem when he saw copy and paste code. To do anything reasonably complex with EU::MM, you have to be able to write Perl 5 code which generates (and modifies with regular expressions) cross-platform Makefiles which themselves call into Perl 5 code because Perl 5 has a sane baseline of well-understood and reliable behavior across platforms in a way that Makefiles and shells do not.

If that's not sufficient horror, consider that the way to customize EU::MM behavior the last time I looked at it (Two notes here. First, its current maintainer refuses to add new features or change existing features because it's so awful to maintain. Second, I wrote tests for some of those behaviors, so I've read and understood the code.) you write a custom superclass called MY from which EU::MM inherits to change the behavior of the various steps of generating cross-platform Makefiles which may or may not invoke Perl 5 to perform shell functions.

I am not making this up and I did not make any typos. EU:MM inherits from your custom class.

Keeping EU::MM viable long past the point where Module::Build did everything n a saner way is but a little crime. (There's a reason almost no one recommends the use of h2xs to make skeletons for new modules anymore; most new modules aren't mere wrappers around C libraries. The need for a compilation step with a pure-Perl distribution seems more than a little bit superfluous.)

Module::Install reinvoking your current CPAN client recursively to install dependencies when your current CPAN client already has a perfectly good way to install dependencies is a slightly larger crime. (I understand the justification; what if someone is trying to install a distribution from a tarball manually without a CPAN client, but is there a Principle of Least Possible Differentiation at work with that design choice?)

I don't particularly care that using M::I as a distribution maintainer means that you have to keep track of every new release of M::I which could fix bugs or make upgrading impossible and release a new version of every one of your distributions with the new M::I because of its autobundling problems, because if you get your kicks that way, more power to you. (Don't expect me to jump up and down for joy at upgrading all of your distributions on my machines, though.)

I never particularly cared for the FUD about Module::Build from some M::I discussions, especially the nonsense about "Module::Build doesn't support --install so it spews files all over the place!" (as if EU::MM ever worked properly there) or "Module::Build doesn't support uninstalling!" (as if anyone ever used that from the CPAN client to know that it worked with any system.)

I appreciate that Module::Install provided a much nicer interface than EU::MM did, and that that interface worked transparently to hide the nasty details of EU::MM. Those are true benefits, and I don't blame anyone for choosing M::I for that reason.

Even so, Module::Install's greatest crime is that it's been a distraction from identifying and fixing the real problems of the CPAN... but that's another post.

Modern Perl: The Book

cover image for Modern Perl: the book

The best Perl Programmers read Modern Perl: The Book.

sponsored by the How to Make a Smoothie guide



About this Archive

This page is an archive of entries from March 2010 listed from newest to oldest.

February 2010 is the previous archive.

April 2010 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Powered by the Perl programming language

what is programming?