views:

313

answers:

6

A couple of years back I participated in writing the best practices/coding style for our (fairly large and often Perl-using) company. It was done by a committee of "senior" Perl developers.

As anything done by consensus, it had parts which everyone disagreed with. Duh.

The part that rubbed wrong the most was a strong recommendation to NOT use many Perlisms (loosely defined as code idioms not present in, say C++ or Java), such as "Avoid using '... unless X;' constructs".

The main rationale posited for such rules as this one was that non-Perl developers would have much harder time with the Perl code base otherwise. The assumption here I guess is that Perl code jockeys are rarer breed overall - and among new hires to the company - than non-Perlers.

I was wondering whether SO has any good arguments to support or reject this logic... it is mostly academic curiosity at this point as the company's Perl coding standard is ossified and will never be revised again as far as I'm aware.

P.S. Just to be clear, the question is in the context I noted - the answer for an all-Perl smaller development shop is obviously a resounding "use Perl to its maximum capability".

+1  A: 

I'd say Moose kills off 99.9% of Perl-isms, by convention, that shouldn't be used: symbol table hackery, reblessing objects, common blackbox violations: treating objects as arrays or hashes. The great thing, is it does all of this without taking the functionality hit of "not using it".

If the "perl-isms" you're really referring to are mutator form (warn "bad idea" unless $good_idea), unless, and until then I don't think you really have much of an argument because these "perlisms" don't seem to inhibit readability to either perl users, or non-perl users.

Evan Carroll
Well, the things you listed were pretty much on the list of things we all 100% agreed were Bad Things in the first place except some very advanced/highly tuned central libraries where people without decent Perl knowledge should not be allowed nearer than 100 feet in the first place :)
DVK
You give way too much credit to Moose. It's the stuff that happens in the interesting methods, not how you define them.
brian d foy
@brian, Stop speaking vaguely all the time: give an example I wrote my whole answer in examples.
Evan Carroll
+5  A: 

What sort of perlisms do you mean?

Good:

  • idiomatic for loops: for(1..5) {} or for( @foo ) {}
  • Scalar context evaluation of arrays: my $count = @items;
  • map, grep and sort: my %foo = map { $_->id => $_ } @objects;

OK if limited:

  • statement modifier control - trailing if, unless, etc.
    • Restrict to error trapping and early returns. die "Bad juju\n" unless $foo eq 'good juju';
    • As Schwern pointed out, another good use is conditional assignment of default values: my $foo = shift; $foo = 'blarg' unless defined $foo;. This usage is, IMO, cleaner than a my $foo = defined $_[0] ? shift : 'blarg';.
    • Reason to avoid: if you need to add additional behaviors to the check or an else, you have a big reformatting job. IMO, the hassle to redo a statement (even in a good editor) is more disruptive than typing several "unnecessary" blocks.
  • Prototypes - use only to create filtery fuctions like map. Prototypes are compiler hints not 'prototypes' in the sense of any other language.
  • Logical operators - standardize on when to use and and or vs. && and ||. All your code should be consistent. Best if you use a Perl::Critic policy to enforce.

Avoid:

  • Local variables. Dynamic scope is damn weird, and local is not the same as local anywhere else.
  • Package variables. Enables bad practices. If you think you need globally shared state, refactor. If you still need globally shared state, use a singleton.
  • Symbol table hackery
daotoad
I'm with you for everything except the use of package-scope variables. Now, I think that case can be made, but it's very much not a "perlism" to begin with. It happens to map very closely to similar constructs in basically every other imperative language out there (e.g. no java programmer is going to have trouble understanding "our" -- it's just like "static"). I suspect you've accidentally inserted a personal peeve.
Andy Ross
Familiarity is not the problem with package vars. The problem is that overuse of globals is a bad idea. If you use package scoped lexicals with accessor functions, at least you have some encapsulation. A configuration object is even better, because it bundles up all those messy accessors. I put the "bad stuff" under 'AVOID' rather than 'NEVER' for a reason. Maybe it doesn't fit here, since this is a language agnostic "globals are bad" suggestion.
daotoad
I'm with you except for statement modifiers. The reasoning is a little ridiculous, there's nothing *big* about reformatting one line (in fact, its a rote operation). If you do that a lot then you might be using them where they shouldn't be. Statement modifiers are handy when you want to emphasize the thing being done over the condition. Conditional assignment is a good example, `$foo = 42 unless defined $foo`, prior to the `//=` operator.
Schwern
@Schwern, conditional assignment is a good one that I use regularly. I forgot to add it to the list. The reformatting thing is a real concern, though. I hate the extra typing it involves. If I can imagine that I might want to add another statement I use the block form.
daotoad
@daotoad - I mostly agree with the reasoning above and used pretty much teh same arguments back when (if not as eloquently put).
DVK
+27  A: 

I write code assuming that a competent Perl programmer will be reading it. I don't go out of my way to be clever, but I don't dumb it down either.

If you're writing code for people who don't know the language, you're going to miss most of the point of using that language. I often find that people want to outlaw Perlisms because they refuse to learn any more than they already know.

Since you say that you are in a small Perl shop, it should be pretty easy to ask the person who wrote the code what it means if you don't understand it. That sort of stuff should come up in code reviews and so on. Everyone continues to learn more about the language as you have periodic and regular chances to review the code. You shouldn't let too much time elapse without other eyeballs looking at someone's code. You certainly shouldn't wait until a week after they leave the company.

As for new hires, I'm always puzzled why anyone would think that you should sit them in front of a keyboard and turn them loose expecting productive work in a codebase they have never seen.

This isn't limited to Perl, either. It's a general programming issue. You should always be learning more about your tools. Most of the big shops I know have mini-bootcamps to bring developers up to speed on the codebase, including any bits of tricky code they may encounter.

brian d foy
I agree with brian. If the ism in question is idiomatic Perl, rather than just one developer's quirky way of doing it, they're going to run into it eventually so why pretend otherwise? You don't code in a little corporate bubble (and if you do, you're probably not learning anything). The converse is also true, if you sit a Perl programmer down to a code base written like Java, and take their tools away, they're going to be hampered. The biggest killer being "no CPAN modules". If its merely unfamiliar, but fine practice once you've learned it, use it. You'll grow your team.
Schwern
"That sort of stuff should come up in code reviews and so on." YES! That is the perfect time to learn and transfer "tribal" things and increase the knowledge of the tribe as a group.
Greg
+7  A: 

I ask myself two simple questions:

  • Am I doing this because it's devilishly clever and/or shows off my extensive knowledge of Perl arcana?

Then it's a bad idea. But,

  • Am I doing this because it's idiomatic Perl and benefits from Perl's distinct advantages?

Then it's a good idea.

I see no justifiable reason to reject, say, string interpolation just because Java and C don't have it. unless is a funny one but I think having a subroutine start with the occasional

return undef unless <something>;

isn't so bad.

Dan
+2  A: 

It must have been, as you say, a few years ago, because Damian Conway has 'cornered the market' in Perl standards with Perl Best Practices for the last few years.

I've worked in a similarly ossified environment - where we were not allowed to adopt the latest best practices, because that would be a change, and no one at a sufficiently high level in the corporate structure understood (or could be bothered to understand) Perl and sign off on moving in to the 21st Century.

A corporation that deploys a technology and retains it, but doesn't either buy in expertise or train up in house, is asking for trouble.

(I'd guess you're working in a highly change-controlled environment - financial perhaps?)

I agree with brian on this by the way.

martin clayton
Of course it's financial. Good guess :)
DVK
A: 

Pick up a copy of Effective Perl Programming: Ways to Write Better, More Idiomatic Perl (2nd Edition), and treat that as a guideline. It contains many of the better idioms and is packed with the little bits of information that will get you writing good Perl style Perl code, as opposed to C or Java (or whatever) style Perl code.

Christopher Cashell