Perl Best Practices (PBP) was released in 2004, about 7 years ago. Perl is a great language, but its culture of TIMTOWTDI can be a problem. These days, we often hear that “there’s more than one way to do it, but sometimes consistency is not a bad thing either” (TIMTOWTDIBSCINABTE). PBP deserves a lot of credit for encouraging discussion about the downsides of TIMTOWTDI.
PBP has a lot of recommendations. A lot of them are fairly trivial, like recommendations on code formatting. I’m a big fan of using a consistent style throughout a single code base, but I’m flexible about what that style should be. Some of his other recommendations are more meaningful, and deserve some review 7 years later.
I’ll take a look at each recommendation in Chapter 15, Objects, and see how it’s stood up in the era of Modern Perl. Maybe I’ll tackle some other chapters in the future.
“Make object orientation a choice, not a default” and “choose object orientation using appropriate criteria”
Damian presents a list of criteria on when to use OO. This is a great list. Read it, understand it, think about it.
“Don’t use pseudohashes”
Well, they’re gone from the Perl core, so I agree!
“Don’t use restricted hashes”
I never ran across any code using this feature, even back in the early 2000s. Has anyone else? I agree with Damian, but this seems like a non-issue.
“Always use fully encapsulated objects”
“Give every constructor a standard name”
As more and more people use object systems like Moose, Class::Accessor, and so on, this becomes less of an issue.
However, offering alternate constructors can be useful. The DateTime module has a standard
new() constructor, but it also has constructors named
“Don’t let a constructor clone objects”
Again, this seems to have become less of an issue as fewer people hand roll their own OO code. I agree with Damian. Cloning should be a separate, explicit operation.
“Always provide a destructor for every inside-out class”
Damian really pushes inside-out objects in PBP. At one point, it seemed like inside-out objects were the next big thing in Perl, but I don’t think they really took off, especially compared to Moose and Class::Accessor.
This recommendation is basically irrelevant today.
“When creating methods, follow the general guidelines for subroutines”
Basically, Damian says “write methods like I told you to write subroutines in previous chapters.” That advice in previous chapters is all pretty good, but I won’t go through it here.
“Provide separate read and write accessors”
Damian wants you to write
set_name(). I don’t think this ever took off. My personal preference is
set_name(), though that’s just as unpopular.
I think the real recommendation should be to use read-only attributes as much as possible. Mutability adds complexity to your code. Avoid it whenever possible.
In that context, I’d avoid the
get_name() style. Very little Perl code I’ve seen uses that naming scheme. The naming of writers matters less if they’re rare, but readers will be common, and you should just use the style that everyone else uses.
“Don’t use lvalue accessors”
Indeed. I think the lvalue feature was a waste of time. Really, is writing
$object->foo = 42 so much better than
$object->foo(42)? I don’t get it.
“Don’t use indirect object syntax”
“Provide an optimal interface, rather than a minimal one”
Basically, Damian says that your classes should provide methods that will be as useful as possible for callers. Don’t write an API that makes people do lots of extra work.
For example, with Moose, instead of returning raw array and hash references from accessors, use the Native Traits feature to provide cleaner APIs.
This is a good recommendation, but it’s very difficult to teach this to people. Most people write terrible APIs, period.
“Overload only the isomorphic operators of algebraic classes”
Let me translate this. Damian is saying “don’t get cute with operator overloading, just use it for math-like things”.
I agree, and would go further. I’ve written about how Perl 5′s operator overloading is broken. With that in mind, I suggest avoiding it entirely in most cases.
“Always consider overloading the boolean, numeric, and string coercions of objects”
I disagree. Unfortunately, because of the broken nature of Perl 5 overloading, providing these coercions oftens ends up being useless.
This chapter of PBP holds up pretty well 7 years later. He was out of sync with the community on accessor naming in 2004, and that hasn’t changed. I disagree with him on overloading, but I don’t know that there’s any community agreement on that.
Other chapters talk more about inside-out objects, and I think he missed the mark in thinking those were the future of Perl OO. I’ll cover that in more detail if I review one of those chapters.
His remaining recommendations remain pretty solid in 2011.