The Role of Critique

Over the last week I've been noodling with a minor improvement to Perl Critic to do with private methods and roles. Sometimes I write roles that are essentially importers for utility methods - methods that are essentially imported into the class but don't become part of the public interface. Here's an example of such a role, something that allows you to write $self->_select("SELECT * FROM foo WHERE foo_id",123) on any class that has a dbh attribute.
package SuperProject::Role::WithSelect;

use Moo::Role;

requires 'dbh';

sub _select {
  my $self  = shift;
  my $sql   = shift;
  my @binds = @_;
  return $self->dbh->selectall_arrayref( $sql, { Slice => {} }, @binds);

So what's the problem (aside from the fact that I should have been using DBIx::Class for the databse stuff?)
bash$ perlcritic --verbose 10 SuperProject/Role/
Private subroutine/method '_select' declared but not used at line 7, column 1.
 Subroutines::ProhibitUnusedPrivateSubroutines (Severity: 3)
   By convention Perl authors (like authors in many other languages)
   indicate private methods and variables by inserting a leading underscore
   before the identifier. This policy catches such subroutines which are
   not used in the file which declares them.

   This module defines a 'use' of a subroutine as a subroutine or method
   call to it (other than from inside the subroutine itself), a reference
   to it (i.e. `my $foo = \&_foo'), a `goto' to it outside the subroutine
   itself (i.e. `goto &_foo'), or the use of the subroutine's name as an
   even-numbered argument to `use overload'.
Ooops. Perl::Critic is complaining about that private subroutine that's not used in the role class. I guess I could change the method name from _select to select, but I don't want select to become part of the public interface to the class that's consuming this role. Another option would be to use a ## no critic declaration. But that's tedious, almost every role I write is going to be littered with extranious ## no critic delcarations and that's often a sign that something is seriously wrong. What we need is some way to turn off Subroutines::ProhibitUnusedPrivateSubroutines for all our roles, but leave it on for everything else. And that's what I've been working on with help from Jeff Thalhammer over the last week. With the release of Perl::Critic that was released today you can tweak Subroutines::ProhibitUnusedPrivateSubroutines in your perlcriticrc to automatically turn itself off for a file if somewhere in that file you use a particular module, like, say, Moo::Role.
skip_when_using = Moo::Role

- to blog -

blog built using the cayman-theme by Jason Long. LICENSE