Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Writing a better Modern::Perl

by EvanCarroll (Chaplain)
on Oct 07, 2010 at 15:45 UTC ( #864021=perlmeditation: print w/replies, xml ) Need Help??

I've always really liked the ideas of Modern::Perl, however I always hated the implementation. Something about a Modern::Perl hosted on CPAN, that didn't make use of CPAN seemed laughable to say the least. I set out to fix this. My new module nextgen, sits somewhere in between Modern::Perl and perl5i. It's based off of my subjective experience of what the best module on CPAN would consist of /today/.

It makes one bold assumption that isn't present in perl, or other like modules: the package's default meaning is "Class", unless you

use nextgen mode => ':procedural'

I find for myself this is true 99% of the time. Furthermore, I find that when I'm writing classes I want Moose. Spoiler: the other modules this enables are namespace::autoclean, autodie (core in 5.10 anyway), indirect, mro, utf8, strict, and warnings. And, when run with -M on the command line, oose.

I'd write more about it here, but I've already written a decent bit about it on the pod, check out nextgen and tell me what you think.

Evan Carroll
The most respected person in the whole perl community.

Replies are listed 'Best First'.
Re: Writing a better Modern::Perl
by moritz (Cardinal) on Oct 07, 2010 at 16:59 UTC
    I fully agree with JavaFan about having to remember (and let's not forget, also having to install) various new policy modules - they don't seem to be worth the trouble for me.

    A few minor nits:

    IMHO 'nextgen' (and also 'Modern' in Modern::Perl) is a bad toplevel namespace; a Policy:: or policy:: namespace would fit better. Hubris is supposed to be a virtue for Perl programmers, but only while writing code, not while interacting with the rest of the world.

    autodie (will be core in 5.12 anyway)

    That sounds as if 5.12 were the future. It's not, it's been released almost half a year ago. That said, autodie was also included in 5.10.1

    Another thing to mention is that loading utf8 does more harm than good, unless you also set up decoding and encoding IO layers for input and output.

    Perl 6 - links to (nearly) everything that is Perl 6.

      Fixed on autodie reference, I was using it before 5.10 and that was my oversight. Glad to know it is in core now, and has been for a while!

      As, for utf8, I wholly disagree, the encoding of the perl source and of the IO stream should be separate. You can argue that both should be UTF8: but, I don't think you can logically argue that the Perl source shouldn't be utf8. Even if you're not using UTF8, and even if the files you want to read aren't using utf8, the authors using nextgen and contributing to CPAN should be encoding their perl source in UTF8. We shouldn't assume they have the same legacy-needs you do.

      Evan Carroll
      The most respected person in the whole perl community.
        but, I don't think you can logically argue that the Perl source shouldn't be utf8.

        That's not at all what I'm arguing.

        I simply made the experience that concatenating binary strings and decoded strings lead to nasty errors. So if you don't bother to decode strings on input, telling Perl that the source file is UTF-8 is harmful.

        If your script or module is written in UTF-8, input and output data is UTF-8, but you don't decode or encode, everything "works" in the sense that the output is correct UTF-8 (though of course the strings don't follow proper Unicode semantics internally). In this case use utf8; leads to incorrect output.

        Perl 6 - links to (nearly) everything that is Perl 6.
Re: Writing a better Modern::Perl
by JavaFan (Canon) on Oct 07, 2010 at 16:06 UTC
    tell me what you think.
    Well, I don't think much of it.

    First of all, half of the modules it loads, aren't my cup of tea.

    But, more importantly, I don't like all those modules that load pragmas for you. I rather much have code where I can just look at the beginning of the file and see that strict, warnings, autodie, and some other pragmas loaded. Do not expect from the people coming after you to memorize a matrix of "modern" pragmas, and what the enable for you.

    I do appreciate the effort of avoiding to type 'use strict; use warnings;', etc. But then, for me, "use nextgen;" will be 12 or 13 characters too long. I can have my cake (less typing) and eat it (see the loaded pragmas in the code) with 1 or 0 keystrokes. A single keystroke in my editor loads the template - and if I start off with an empty .pm file, I don't even have to give the single keystroke.

    But even if I work on a system where I don't have my editor macros available, I still rather "use 5.010; use strict; use warnings;" than "use nextgen;" (or any other pragma with a similar effect). The two seconds extra it takes to type are earned a hundred fold for each developer after me who has to look up what the hell 'use nextgen' enables.

      I still rather "use 5.010; use strict; use warnings;"

      One less now

      $ perl -e'use 5.012; print $x' Global symbol "$x" requires explicit package name at -e line 1. Execution of -e aborted due to compilation errors.
        I will still write 'use strict;' even if I do a 'use 5.012'. It's a little effort, and I'm not going to assume everyone will know that at some point in time use implied use strict, and that they know at which point in time that was.

        Besides, writing "use 5.012;" without a "use strict;" runs the risk someone removes the "use 5.012;" (not unreasonable if there's nothing in the code that actually needs 5.012...), and then have it be without strict.

        I never liked the idea that "use 5.XXX" implies subtle changed behaviour other than "without the mentioned version, it's unlikely to compile". I prefer "use 5.XXX" to mean one of "if you try to compile this with 5.YYY, where YYY < XXX, you'll fail" or "this code will trigger a bug in 5.YYY, which was fixed in 5.XXX". The implicite turning on of strict isn't such a change. Now it mean "if you try to run this with 5.YYY, I'm going to keep quiet if you screw up". Not what I expect of a helpful language.

        I will only slap a "use 5.012;" label on my code if there's actually anything in my code that won't run on 5.010. So far, I've written next to no code that needs 5.012. I'm not going to artificially restrict my code to a certain version just so I don't have to type a few keystrokes (which I don't have to type in the first place - an editor macro does that for me).

      Right, well by extension you could not `use warnings` - because it essentially does the same by enabling :all, and instead you can use each different type of warning explicitly. You could do the same thing with strict too! Even CORE has to make some defaults: $[ defaults to 0.

      Other than the extremely weak argument you present, the point I'd like to make is that there is a level of reasonableness to getting better defaults. That comes at the cost of "defaults" - choices being made by someone else that *might* not apply to you, but *may* very well be so crafted as to benefit you in every application.

      Evan Carroll
      The most respected person in the whole perl community.
        Other than the extremely weak argument you present

        I don't think JavaFan's argument is weak, and you didn't do anything serious to prove your point.

        Also if you don't respect the opinions of those that answer, why ask for opinions in the first place?

        Perl 6 - links to (nearly) everything that is Perl 6.
        I have nothing against defaults.

        However, if you would be happy with the defaults, you wouldn't toss out one module, and write your own with a different set of defaults.

        I know what "defaults" I get when using 'use warnings', or 'use strict'. I also know they are very unlikely to change, and, if they do, it will require a major Perl release. The defaults for 'use strict' haven't changed since 5.000.

        But with Modern::Perl, nextgen, and other modules enabling lexical pragmas outside of their lexical scope, they aren't defaults. The are choices, choices made by the authors. And regardless whether one agrees with the authors choices, for each module you encounter in code you inherit/maintain, you'll have to find out what it does. That takes an effort.

        Writing good Perl code isn't golfed code. Mentioning the pragmas you're going to use in your program only takes a few seconds of typing. IMO, the benefits of mentioning the pragmas your using far outweight the cost of typing a few lines. It's just like comments. I spend quite a few keystrokes on comments. Sometimes, the comments even look like "boilerplate". Guess what, I don't hide that in a module either.

        EvanCarroll: "Hey, can you give me a ride to the store?"
        Friend: "Sure, let's go."
        EvanCarroll: "Dude, your car sucks."

        Asking someone for their opinion, then arguing against it, teaches people that they should not bother responding to your requests.


Re: Writing a better Modern::Perl
by sundialsvc4 (Abbot) on Oct 08, 2010 at 13:22 UTC

    There is a very delicate balance to be struck here.   On the one hand, we want it to be convenient for us to write accurate, robust software.   On the other hand, we must always be able to look at a piece of software and to ascertain, correctly, what it will do.   Programmers handle this by devising standard practices within each “shop.”   They dub their favorite things, “best practices,” and subsequently stand around the Monastery's electronic water-cooler, bickering in a friendly way about what “best” actually means; what is “better.”

    Being good Perl programmers, they practice laziness and hubris.   They automate things.   Then, they insist that everyone else should automate things just the way they did.   But change happens slowly, if at all.

    They’re professionals, often with twenty or thirty years in.   Among the very best.   The disagreements, and the insistence, and the resistance, all come from people who know whereof they speak.   Change happens.   Slowly.

    I have learned to be reluctant about things that are “too convenient.”   Specifically, about things that place substantial influences over the behavior of a piece of source-code, anywhere outside of that piece of source-code.   In my experience, such things, well-intentioned though they might be, create substantial difficulties.   Call me a Luddite if you want to... ;-)   I can be convinced, but not quickly.

      They’re professionals, often with twenty or thirty years in.

      I didn't write Modern::Perl for professionals who know the ins and outs of Perl 5 and who have customized their development environments such that their editors always insert the appropriate preludes for them.

      I wrote it for people who don't yet know enough Perl 5 to understand the half-dozen lines of code that pretty much every new Perl 5 program begun today really ought to have.

        I see that.   And, I did not intend my comment to be in any way critical of, nor disrespectful of, you or your work.

        Indeed, it is highly desirable to have modules that make it easier (and more trouble-free) to “DDRT=Do The Right Thing.”   The natural and understood trade-off is, the need to understand precisely what they are doing ... and the need to improve-upon the “DDRT” module without breaking a mountain of existing code that has been written to use it.   Every ointment has its houseflies...

        The bugaboo is this:   if we have n Perl modules that are all relying upon the behavior of (some hypothetical) DDRT 1.0, those n modules now have a material dependency ... not just to DDRT 1.0, but to one another.   Not only might you find it to be difficult to change or to replace the DDRT module, but also you might find it problematic to “do anything different” in any one of the client modules.   It might be “all, or nothing.”

        If we found it business-necessary to implement “different” behavior in some particular module, we might find that we have no practical choice but to replace the DDRT module calls with “what that module would have done, only slightly different.”   And, when that continues to happen over time, the benefits begin to disappear, or are negated.

        Alternatively, some clever programmer might find a way to “work around” the not-quite-desired behavior or implementation of DDRT through resorting to some kind of “clever trick.”   Something that leverages a side-effect, or an undocumented subroutine, or something even more obscure.   “It works!”   But... how soon will it be forgotten?   And, when we replace DDRT with NAIDDRT (“New And Improved...”), suddenly there are problems.   Maybe the problems spew all over our production-schedule, but maybe ... far worse ... they don’t.   Or, they initially do not appear to.   It is three o’clock in the morning.   Your beeper just went off ...

        Houseflies do not go to sleep at night.

        Again, I do not intend anything negative by these observations.

Re: Writing a better Modern::Perl
by Anonymous Monk on Oct 08, 2010 at 04:18 UTC

    Some fedback from my end:

    Now that we have Devel Declare and the other syntax extensions with sufficiently good sugar. The emphasis must be on using them as a set of standard(a step lower than defaults) so that people who program feel they are a part of the language itself(more or less like a default features). Currently writing lines of boilerplate code before using anything is a big problem. Also not to mention downloading and configuring all those modules is also a little problematic. Downloading and using something from CPAN gives a feel of using a library and not a syntax extension.

    It will be nice if there is a out-of-the-box package of a sort that plugs these syntax extensions in to the perl installation. Without one having to bother about module dependency,downloading,installing and telling the project mates that its from CPAN. If backwards compatibility is problem it can be taken care of after all its just a package. It must be like download/install Perl and download/install syntax extension package and you are ready to use without having to bother about CPAN, boilerplate, modules, dependencies, versions etc etc. It must be like using Perl out of the box.

    Quoting Larry Wall from here

    My advice, if you want to have people user your language, is to do as much work on their behalf as you can.

Re: Writing a better Modern::Perl
by Anonymous Monk on Oct 09, 2010 at 01:37 UTC
    I personally can't wait for PostModern::Perl. Oh wait...
      Everything will be available except for sound defaults. Which is a sad thing.