EzDevInfo.com

Perl-Critic

The leading static analyzer for Perl. Configurable, extensible, powerful. Perl::Critic instantly find bugs in your perl code

Is there anything like PPI or Perl::Critic for C?

PPI and Perl::Critic allow programmers to detect certain things in the syntax of their Perl programs.

Is there anything like it that will tokenize/parse C and give you a chance to write a script to do something with that information?


Source: (StackOverflow)

Perl::Critic: Life after Moose?

I've started a conversion of a project to Moose and the first thing I noticed was that my critic/tidy tests go to hell. Moose, Tidy and Critic don't seem to like each other as much as they used to.

Are there docs anywhere on how to make critic/tidy be more appreciative of the Moose dialect? What do most Moose users do? Relax/ditch critic for the more heavy Moose modules? Custom policies?


Source: (StackOverflow)

Advertisements

Perl::Critic "Don't use this method"-type rule

We have been using Perl::Critic here at work to enforce our code conventions. Recently we ran into issues with /tmp directory getting filled up due to the Temp::File::tempdir function. tempdir cleans up when the Perl process terminates, but since our entire backend is a Perl process, this only occurs when the server itself gets restarted (not very often). We want to encourage developers to use the newdir object method in the future, which cleans up after itself as soon as the object goes out of scope.

Basically, we're trying to mark Temp::File::tempdir as a code convention violation, but I can't seem to find any rule that would be similar on CPAN. I understand that this is hard to enforce in a dynamically-typed language without introducing false positives, but I would expect someone has ran into similar issue in the past with another deprecated function. We're not expecting to catch all the tricky cases either, only the most obvious uses of Temp::File::tempdir. The idea is to discourage accidental use of tempdir when newdir could do the job, not to catch all attempts to fool the critic (developer could always just use ## no critic). It would probably be enough to complain when tempdir is used if use Temp::File is defined (preferably checking that nothing else redefines tempdir) and when Temp::File::tempdir is used.

Is there already something similar, or should I start from scratch? Thanks


Source: (StackOverflow)

Why does Perl::Critic dislike using shift to populate subroutine variables?

Lately, I've decided to start using Perl::Critic more often on my code. After programming in Perl for close to 7 years now, I've been settled in with most of the Perl best practices for a long while, but I know that there is always room for improvement. One thing that has been bugging me though is the fact that Perl::Critic doesn't like the way I unpack @_ for subroutines. As an example:

sub my_way_to_unpack {
    my $variable1 = shift @_;
    my $variable2 = shift @_;

    my $result = $variable1 + $variable2;
    return $result;
}

This is how I've always done it, and, as its been discussed on both PerlMonks and Stack Overflow, its not necessarily evil either.

Changing the code snippet above to...

sub perl_critics_way_to_unpack {
    my ($variable1, $variable2) = @_;

    my $result = $variable1 + $variable2;
    return $result;
}

...works too, but I find it harder to read. I've also read Damian Conway's book Perl Best Practices and I don't really understand how my preferred approach to unpacking falls under his suggestion to avoid using @_ directly, as Perl::Critic implies. I've always been under the impression that Conway was talking about nastiness such as:

sub not_unpacking {
    my $result = $_[0] + $_[1];
    return $result;
}

The above example is bad and hard to read, and I would never ever consider writing that in a piece of production code.

So in short, why does Perl::Critic consider my preferred way bad? Am I really committing a heinous crime unpacking by using shift?

Would this be something that people other than myself think should be brought up with the Perl::Critic maintainers?


Source: (StackOverflow)

Is there a better way to write Perl regexes with /x so the code is still easy to read?

I ran Perl::Critic on one of my scripts, and got this message:

Regular expression without "/x" flag at line 21, column 26. See page 236 of PBP.

I looked up the policy information here, and I understand that writing regular expressions in extended mode will help anyone who is looking at the code.

However, I am stuck as how to convert my code to use the /x flag.

CPAN Example:

# Match a single-quoted string efficiently...

m{'[^\\']*(?:\\.[^\\']*)*'};  #Huh?

# Same thing with extended format...

m{
    '           # an opening single quote
    [^\\']      # any non-special chars (i.e. not backslash or single quote)
    (?:         # then all of...
        \\ .    #    any explicitly backslashed char
        [^\\']* #    followed by an non-special chars
    )*          # ...repeated zero or more times
    '           # a closing single quote
}x;

This makes sense if you only look at the regex.

My Code:

if ($line =~ /^\s*package\s+(\S+);/ ) {

I am not exactly sure how to use an extended regex inside of an if statement. I can write it like this:

    if (
        $line =~ /
        ^\s*    # starting with zero or more spaces
        package
        \s+     # at least one space
        (\S+)   # capture any non-space characters
        ;       # ending in a semi-colon
        /x
      )
    {

And this works, but I think this is almost harder to read than the original. Is there a better way (or a best practice way) to write this? I guess I could create a variable using qr//.

I'm not really looking for advice on re-writing this specific regex (although if I can improve it, I'll take advice) - I'm more looking for advice on how to expand a regex inside of an if statement.

I know Perl::Critic is just a guideline, but it would be nice to follow it.

Thanks in advance!

EDIT: So after receiving a few answers, it became clear to me that making a regex multi-line with comments is not always necessary. People who understand basic regex should be able to understand what my example was doing - the comments I added were maybe a little unnecessary and verbose. I like the idea of using the extended regex flag, but still embedding spaces in the regex to make each part of the regex a little more clear. Thanks for all the input!


Source: (StackOverflow)

Are there any good automated frameworks for applying coding standards in Perl?

One I am aware of is Perl::Critic

And my googling has resulted in no results on multiple attempts so far. :-(

Does anyone have any recommendations here?

Any resources to configure Perl::Critic as per our coding standards and run it on code base would be appreciated.


Source: (StackOverflow)

How to detect unreachable code in Perl conditional which always evaluates to false?

I'm new to Perl, and am currently tasked with tidying and maintaining a large and pretty messy Perl project. I'm using perl-critic to help me detect issues in the code (and also to teach me best practices).

The existing code has places where the coder has created unreachable code. For instance, they added '&& 0' as a lazy way of commenting out some of the code branches:

if ($req->param('donut') && 0) {
    unreachable code... 
} else {
    always branches to here...
}

I'd hoped that perl or Critic would warn me about unreachable code in such instances (where a conditional has a constant value evaluating to false), but it doesn't.

Is there a tool or a piece of script I could use which can reliably detect this kind of thing?

Obviously I could search for '&& 0' in the source but there are a number of ways that the coder could have created unreachable code besides appending '&& 0' to an if statement.


Source: (StackOverflow)

Module ends in "1;", perlcritic complains that it doesn't

Have a simple module

package Rrr;
use 5.014;
use warnings;
use namespace::sweep;
use Moo;
use Method::Signatures::Simple;

BEGIN {
    our $VERSION = '0.0.1';
}

has 'root' => (
    is => 'rw',
    default => 'root'
);

method func {
    say 'This is the func method from ' . __PACKAGE__ . ' with value: ', $self->root;
}

1;

The perlcritic -1 says

Code is not tidy at line 1, column 1.  See page 33 of PBP.  (Severity: 1)
Module does not end with "1;" at line 17, column 1.  Must end with a recognizable true value.  (Severity: 4)
Return value of flagged function ignored - say at line 18, column 5.  See pages 208,278 of PBP.  (Severity: 1)

How to make perlcritic happy?

EDIT - based on @toolic's comment

Yes, the tidy helps with the 1st problem (but the Code is not tidy at line 1, column 1. isn't much helpful message), as the diff is:

13c13
<     is => 'rw',
---
>     is      => 'rw',
18c18,19
<     say 'This is the func method from ' . __PACKAGE__ . ' with value: ', $self->root;
---
>     say 'This is the func method from ' . __PACKAGE__ . ' with value: ',
>       $self->root;

But still got the:

Module does not end with "1;" at line 17, column 1.  Must end with a recognizable true value.  (Severity: 4)
Return value of flagged function ignored - say at line 18, column 5.  See pages 208,278 of PBP.  (Severity: 1)

My percritic:

$ perlcritic --version
1.125

Source: (StackOverflow)

Perlcritic - Two argument "open" error

I have a script and I am trying to elimate bad practices using perlcritic.

One line I have is as follows:

open(my($FREESPCHK), $cmdline ) || &zdie($MSG_PASSTHRU,"Error checking free space of file system.");

This gives this error: Two-argument "open" used at line xxx, column x. See page 207 of PBP. (Severity: 5)

Any ideas on how to fix it?


Source: (StackOverflow)

Perl Critic: Comma used to separate statements

Follow code is not accepted by Critic, severity 4:

return {
    'debug'  => $debug,
    'identifier' => $identifier
};

I get this error:

# Perl::Critic found these violations in "filename.pl":
# Comma used to separate statements at line 356, column 3.  See pages 68,71 of PBP.  (Severity: 4)

But this code is accepted without any remark:

my $result = {
    'debug' => $debug,
    'identifier' => $identifier
};

return $result; 

Is it really better to write my return using a temporary variable, or is the critic wrong in detecting a Comma used to separate statements while I'm just constructing and returning a hashref?


Source: (StackOverflow)

What is the correct way to exclude RequireRcsKeywords from Perl Critic?

I'm trying to exclude checks of Perl Critic's RequireRcsKeywords in a single Perl script. I don't want to change my default policy in .perlcriticrc so I added a "no critic" line to the top of the source. Despite that change, Perl Critic still complains about the lack of RCS keywords.

Here is my test case (critictest.pl):

#!/usr/bin/perl
## no critic (RequireRcsKeywords)
use warnings;
use strict;
print "Hello, World.\n";

When I execute perlcritic -1 --verbose 8 critictest.pl I get the following output:

[Miscellanea::RequireRcsKeywords] RCS keywords $Id$ not found at line 1, column 1.  (Severity: 2)
[Miscellanea::RequireRcsKeywords] RCS keywords $Revision$, $HeadURL$, $Date$ not found at line 1, column 1.  (Severity: 2)
[Miscellanea::RequireRcsKeywords] RCS keywords $Revision$, $Source$, $Date$ not found at line 1, column 1.  (Severity: 2)
[Modules::RequireVersionVar] No package-scoped "$VERSION" variable found at line 1, column 1.  (Severity: 2)
[Miscellanea::ProhibitUselessNoCritic] Useless '## no critic' annotation at line 2, column 1.  (Severity: 2)
[InputOutput::RequireCheckedSyscalls] Return value of flagged function ignored - print at line 5, column 1.  (Severity: 1)

I know that Perl Critic is working because if I add ## no critic (RequireCheckedSyscalls) then that error in the output goes away. I also tried adding `## no critic (Miscellanea::RequireRcsKeywords) but that didn't cause any change. What is the correct way to tell Perl Critic to ignore the RequireRcsKeywords policy in my file without having to use an external policy file?

EDIT: I'm using Perl 5.10.1, Perl Critic 1.108, and Debian 6.0.3.


Source: (StackOverflow)

How do I enable PerlCritic support in Komodo IDE 5.1 on Windows?

I'm trying to enable PerlCritic support in Komodo.

The official word from ActiveState, the makers of Komodo IDE 5.1 (Win 32) is:

"To enable PerlCritic support, please install the 'Perl-Critic' and 'criticism' modules."

Well, installing Perl-Critic was a piece of cake:

ppm install Bundle-Perl-Critic

However, I've search every repository in PPM4, (trouchelle and the usual suspects) and they don't seem to have the module called 'criticism'. I've installed lots of modules using CPAN and PPM, but this module proves to be the most elusive so far. Am I missing something here?

Has anyone got any luck enabling PerlCritic support in Komodo 5.1 on Windows? Hope to hear from you. The feature works perfectly in MacOS and Linux though...hmmm.

alt text


Source: (StackOverflow)

Is it better to croak() or to die() when something bad happens in Perl?

perlcritic complaints that the following code, some boilerplate DBI stuff that works perfectly fine, should croak instead of die:

# Connect to database
my $db_handle = DBI->connect( $url, $user, $password ) or die $DBI::errstr;

All this, while die seems to work fine for me.

I would think for a samurai Perl warrior, croak is less honorable than actually die when things go awry. Jokes apart

Why should I croak instead of die?

What are the consequences of not heeding perlcritic's advice?


Source: (StackOverflow)

How can we catch side comments using Perl::Tidy or Perl::Critic?

My department is currently settling on some general code best practices, which we would like to somewhat enforce, providing developers with Perl::Tidy and Perl::Critic configurations.

Now we are having problems with side comments. The side comment is this:

my $counter = 0;  # Reset counter

We would prefer to not have side comments at all, since in most cases they can be written above the code in question, where they are more easily read. If at all possible, a Perl::Tidy solution would be perfect, which would move a side comment to the line above it, second-best would be a Perl::Critic policy (which I haven't found at CPAN either) and third-best and last would be developers taking care to point those comments out when they do code reviews.

Is it possible to implement with Perl::Tidy or Perl::Critic?


Source: (StackOverflow)

perlcritic: eval "require $module";

While digging in some old source code I saw the following:

my $module = $some{module};
eval "require $module";
die "Bad module\n$@" if $@;

while I understand what the code does, it tries "require" a module and die when it is unsuccessful - the perlcritic complains about it

Expression form of "eval" at line 331, column 13. See page 161 of PBP. (Severity: 5)

Unfortunately I havent the PBP book, so wondering what is the correct method of the above...

Also, in the same source found:

sub test_repo_file {
    my($self, $repo, $test) = @_;
    my $abspath = repo_abs_path($repo);
    return "eval -$test $abspath";
}

Here doesn't understand what solves the "eval", and the perlcritic complains again for the "string eval"...

Can somebody please explain the basic points about the "string eval" and how to write the above correctly?


Source: (StackOverflow)