The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Perl::Critic::TODO - Things for Perl::Critic developers to do

SOURCE

    #######################################################################
    #      $URL: http://perlcritic.tigris.org/svn/perlcritic/trunk/Perl-Critic/TODO.pod $
    #     $Date: 2008-10-26 04:26:16 -0500 (Sun, 26 Oct 2008) $
    #   $Author: thaljef $
    # $Revision: 2814 $
    #######################################################################

SEE ALSO

Perl-Critic-More is a separate distribution for less-widely-accepted policies. It contains its own TODO.pod.

NEW FEATURES

  • Report Safari sections in addition to book page numbers.

  • Add --files-with-violations/-l and --files-without-violations/-L options to perlcritic.

    Just print out file names. I could have used this at work when combined with --single-policy.

        gvim `perlcritic --single-policy QuotedWordLists -l`
  • Add a file Behavior.

  • Allow values of (at least) string-list Parameters to be specified in a file.

    For the benefit of PodSpelling, etc.

  • Enhance string-list Behavior to allow specification of delimiters.

    For things like RequirePodSections.

  • Add queries to --list option to perlcritic.

    List Policies based upon severity, theme, and (what I want this second) applies_to.

  • Add formatting of --list output.

    Support Jeff Bisbee's use case (he dumps all the policies in severity order with full descriptions and other metadata).

  • Support for #line 123 "filename" directives.

    For code generators and template languages that allow inline Perl code.

    Yes, somebody has an in-house templating system where they've written a custom test module that extracts the perl code from a template and critiques it.

    Actually, this would be useful for programs: Module::Build "fixes" shebang lines so that there's the bit about invoking perl if the program is attempted to be run by a Bourne shell, which throws the line numbers off when using Test::P::C on the contents of a blib directory.

    This actually requires support from PPI.

  • Enhance statistics.

    - Blank line count

    - POD line count

    - Comment line count

    - Data section count

  • Detect 5.10 source and enable stuff for that.

    For example, treat say as equivalent to print.

  • Support a means of failing if a Policy isn't installed.

    For example, the self compliance test now depends upon a Policy in the More distribution.

    Something like using a "+" sign in front of the Policy name in its configuration block, analogous to the "-" sign used for disabling a policy, e.g. "[+Example::Policy]".

  • Threading

    Pretty obviously, Perl::Critic is readily parallizable, just do a document per thread. ("readily" being conceptual, not necessarilly practical) Although there's now Policy::prepare_to_scan_document(), given perl's thread data sharing model, this shouldn't be an issue.

  • Add support in .run files for regexes for violation descriptions.

  • Add an "inverse mode": complain about "## no critic" that doesn't eliminate any violations.

    Alias on P::C.

    For example, Perl::Critic helps both helps educate developers and reduce the time cost of bugs and weird uses of Perl, but at the expense of having to maintain nocritic entries permanently, which themselves have education and time costs.

    And the goal of the Perl Critic team is that the education and time cost of using Perl::Critic is significantly less than the education and time costs of NOT using Perl::Critic.

    In order to allow people to get rid of "## no critic" markers, create a mode that tells them which markers don't actually hide any violations.

  • Get end of violation description and explanation punctuation consistent.

    Elliot wants messages to read nicely. So, ensure that there's a period at the end if the policy author hasn't provided a terminal punctuation mark.

BUGS/LIMITATIONS

Document bugs for individual Policies in the Policies themselves. Users should be aware of limitations. (And, hey, we might get patches that way.)

OTHER PBP POLICIES THAT SEEM FEASIBLE TO IMPLEMENT

  • Modules::RequireUseVersion [405-406]

  • Modules::RequireThreePartVersion [405-406]

  • Objects::ProhibitRestrictedHashes [322-323]

    Look for use of the bad methods in Hash::Util.

  • Objects::ProhibitLValueAccessors [346-349]

    Look for the :lvalue subroutine attribute.

  • Objects::ProhibitIndirectSyntax [349-351]

    While the general situation can't be handled, we can look for a configured set of names. Especially should be able to complain about new Foo() by default.

NON-PBP POLICIES WANTED

  • NamingConventions::ProhibitMisspelledSymbolNames

    The idea behind this policy is to encourage better names for variables and subroutines by enforcing correct spelling and prohibiting the use of home-grown abbreviations. Assumng that the author uses underscores or camel-case, it should be possible to split symbols into words, and then look them up in a dictionary (see PodSpelling). This policy should probably have a similar stopwords feature as well.

  • Documentation::RequireModuleAbstract

    Require a =head1 NAME POD section with content that matches \A \s* [\w:]+ \s+ - \s+ \S. The single hyphen is the important bit. Also, must be a single line.

  • Expressions::RequireFatCommasInHashConstructors

  • ErrorHandling::RequireLocalizingEvalErrorInDESTROY

    Prevent $@ from being cleared unexpectedly by DESTROY methods.

        package Foo;
    
        sub DESTROY {
            die "Died in Foo::DESTROY()";
        }
    
        package main;
    
        eval {
            my $foo = Foo->new();
    
            die "Died in eval."
        }
        print $@;   # "Died in Foo::DESTROY()", not "Died in eval.".

    See http://use.perl.org/~Ovid/journal/36767.

  • Expressions::ProhibitDecimalWithBitwiseOperator

  • Expressions::ProhibitStringsWithBitwiseOperator

  • InputOutput::ProhibitMagicDiamond

    Steal the idea from B::Lint.

  • TBD::AllProgramsNeedShebangs

    Anything that is a program should have a shebang line. This includes .t files.

  • BuiltInFunctions::RequireConstantSprintfFormat

  • BuiltInFunctions::RequireConstantUnpackFormat

    http://diotalevi.isa-geek.net/~josh/yapc-lint/slides/slide5.html

  • Miscellanea::ProhibitObnoxiousComments

    Forbid excessive hash marks e.g. "#### This is a loud comment ####". Make the obnoxious pattern configurable

  • ValuesAndExpressions::RequireNotOperator

    Require the use of "not" instead of "!", except when this would contradict ProhibitMixedBooleanOperators. This may be better suited for Perl::Critic::More.

  • Modules::RequireExplicitImporting

    Require every use statement to have an explicit import list. You could still get around this by calling import directly.

  • Modules::ForbidImporting

    Require every use to have an explicitly empty import list. This is for folks who like to see fully-qualified function names. Should probably provide a list of exempt modules (like FindBin);

  • ControlStructures::ProhibitIncludeViaDo

    Forbid do "foo.pl". Not sure about this policy name.

  • Variables::ProhibitUseVars

    Disallow use vars qw(...) and require our $foo instead. This contradicts Miscellanea::Prohibit5006isms. Maybe verify use 5.6 before applying this policy. Low severity.

  • VariablesAndExpressions::ProhibitQuotedHashKeys

    Forbid quotes around hash keys, unless they are really needed. This is against what Damian says. Suggested by Adam Kennedy. Low severity.

  • CodeLayout::ProhibitFunctionalNew

    Good: Foo::Bar->new, Bad: new Foo::Bar

  • RegularExpressions::ProhibitSWSWSW

    Require split instead of m/\s*\w*\s*\w*\s*/. From MJD's Red Flags.

  • VariablesAndExpressions::RequireConstantVersion (low severity)

  • VariablesAndExpressions::ProhibitComplexVersion (medium severity)

    http://rt.cpan.org/Ticket/Display.html?id=20439

  • Documentation::RequireSynopsis

  • Documentation::RequireLicense

    These are simplified versions of Documentation::RequirePodSections.

  • Documentation::RequireValidSynopsis

    The Synopsis section must be all indented and must be syntactically valid Perl (as validated by PPI).

  • Documentation::ProhibitEmptySections

    Any =headN and =over sections must not be empty. This helps catch boilerplate (althought Test::Pod should catch empty =over blocks).

    On the other hand, =item ... sections can be empty, since the item label is content.

  • Miscellaneous::ProhibitBoilerplate

    Complain about copy-and-paste code or docs from h2xs, Module::Starter::*, etc.

    Here's a non-PPI implementation: http://search.cpan.org/src/JJORE/Carp-Clan-5.8/t/04boilerplate.t

  • BuiltinFunctions::ProhibitExtraneousScalarCall

    Recommend that if (scalar @array) be rewritten as if (@array).

  • RegularExpressions::ProhibitMixedDelimiters

    Ban s{foo}(bar)

  • RegularExpressions::ProhibitScalarAsRegexp

    Ban naked srtings as regexps, like:

        print 1 if $str =~ $regexp;

    Instead, it should be:

        print 1 if $str =~ m/$regexp/;

    or

        print 1 if $str =~ m/$regexp/xms;
  • ValuesAndExpressions::RequireInterpolatedStringyEval

    Ensure that the argument to a stringy eval is not a constant string. That's just wasteful. Real world examples include:

      eval 'use Optional::Module';

    which is better written as

      eval { require Optional::Module; Optional::Module->import };

    for performance gains and compile-time syntax checking.

  • RegularExpressions::ProhibitUnnecessaryEscapes

    Complain if user puts a backslash escape in front of non-special characters. For example:

       m/\!/;

    Make exceptions for \", \' and \` since those are often inserted to workaround bugs in syntax highlighting.

    Note that this is different inside character classes, where only ^, ] and - need to be escaped, I think. Caret only needs to be escaped at the beginning, and dash does NOT need to be escaped at the beginning and end. See perlreref.

  • Steal ideas from Dunce::Files.

    Can someone expand this entry, please?

  • ControlStructures::ProhibitAssigmentInConditional

  • ValuesAndExpressions::RequireConstantBeforeEquals

  • ValuesAndExpressions::RequireConstantBeforeOperator

    http://use.perl.org/~stu42j/journal/36412

    Just about everyone has been bitten by if ($x = 10) { ... } when they meant to use ==. A safer style is 10 == $x because omitting the second = yields a noisy compile-time failure instead of silent runtime error.

    ProhibitAssigmentInConditional complains if the condition of a while, until, if or unless is solely an assignment. If it's anything more complex (like if (($x=10)){} or while ($x=$y=$z){}), there is no warning.

    RequireConstantBeforeEquals complains if the left side of an == is a variable while the right side is a constant.

    RequireConstantBeforeOperator complains if the left side of any comparison operator (==, eq, <, etc) is a variable while the right side is a constant.

  • InputOutput::ProhibitUTF8IOLayer

    http://www.perlfoundation.org/perl5/index.cgi?the_utf8_perlio_layer

  • BuiltinFunctions::ProhibitExit(?:InModules)?

    Forbid exit() in files that lack a shebang. Inspired by http://use.perl.org/~Ovid/journal/36746 and an analgous checker in FindBugs.

  • Modules::ProhibitRedundantLoading

    Don't allow a package to "use" the same module more than once, unless there is a "no <module>" between them.

    See https://rt.cpan.org/Ticket/Display.html?id=38074.

REFACTORINGS and ENHANCEMENTS

  • Create constants for the PPI location array elements.

  • Some means of detecting "runnaway" ##no critic

    Elliot was talking to a couple of users at ETech and one of their major concerns was that they were using ##no critic and forgetting to do a ##use critic after the problematic section. Perhaps an option to perlcritic to scan for such things is in order.

  • Change API to use named parameters

    Most of the methods on the public classes use named parameters for passing arguments. I'd like to extend that pattern to include all object-methods. Static methods can still use positional parameters.

  • Enhance P::C::critique() to accept files, directories, or code strings

    Just like bin/perlcritic does now.

  • Add -cache flag to bin/perlcritic

    If enabled, this turns on PPI::Cache:

        require PPI::Cache;
        my $cache_path = "/tmp/test-perl-critic-cache-$ENV{USER}";
        mkdir $cache_path, oct 700 if (! -d $cache_path);
        PPI::Cache->import(path => $cache_path);

    This cachedir should perhaps include the PPI version number! At least until PPI incorporates its own version number in the cache.

    (see t/40_criticize.t for a more robust implementation)

  • Use hash-lookup instead of List::MoreUtils::any function.

    In several places, Perl::Critic uses List::MoreUtils::any to see if a string is a member of a list. Instead, I suggest using a named subroutine that does a hash-lookup like this:

        my %logical_ops = hashify( qw( ! || && ||= &&= and or not ) );
        sub is_logical_op { return exists $logical_ops{ $_[0] }; }

    Question: Why?

    Answer: Readability, mostly. Performance, maybe.

  • Refactor guts of perlcritic into a module (Perl::Critic::App ??)

    Because it is getting unwieldy in there.

PPI BUGS

We're waiting on the following bugs to get fixed in a CPAN release of PPI:

PPI::Token::descendant_of()

Exists in svn. Replace _descendant_of() in RequireCheckingReturnValueOfEval with that, once it is released, because it's faster and native.

Newlines

PPI does not preserve newlines. That makes CodeLayout::RequireConsistentNewlines impossible to implement under PPI. For now, it's implemented by pulling the source out of the file and skipping PPI.

It's unlikely that PPI will support mixde newlines anytime soon.

Operators

ValuesAndExpressions::ProhibitMismatchedOperators has two workarounds for PPI bugs with parsing operators. Many of these bugs have been fixed in PPI, so it would be good to check if those workarounds are still needed.

Regexp methods

Not strictly a bug -- the PPI Regexp classes have a dearth of accessor methods as of v1.118, meaning that we have to do messy digging into internals. I wrote Perl::Critic:Utils::PPIRegexp to encapsulate this messiness, but it would be nicer to have an official interface in PPI.

QuoteLike::Words in the place of a ForLoop

PPI mis-parses <for qw<blah {}>>.