SlideShare a Scribd company logo
1 of 39
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Customizing and Extending Perl Critic Josh McAdams
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 A Quick Review - What is Perl Critic ... a static source code analyzer for Perl code ... a system of policies that are enforced on your code ... written by Jeffrey Ryan Thalhammer #!/usr/bin/perl print “Hallo, Denmark”;
Customizing and Extending  Perl Critic Nordic Perl Workshop 2007 A Quick Review --(0)> perlcritic hello_denmark.pl  Code before strictures are enabled at line 3, column 1.  See page 429 of PBP.  (Severity: 5) ... is the jarring your memory? Running perlcritic...
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Customizing Perl Critic - How do you customize Perl Critic ... we saw much of this in the “Introduction” talk ... you can ... ignore policies ... assign new severities to policies ... group policies into themes ... pass constructor arguments to policies
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Customizing Perl Critic --(0)> cat ~/.perlcriticrc severity = 2 top = 5 exclude = Editor::RequireEmacsFileVariables Miscellanea::RequireRcsKeywords  [ControlStructures::ProhibitPostfixControls] severity = 4 allow = if unless theme = iffy Looking into a .perlcriticrc file... ... but what about extending Perl Critic? The default severity to report How many violations to report Policies to ignore Change the default severity for a policy Pass arguments to the policy constructor, in this case telling it to allow trailing ifs and unlesses Apply a new theme
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Extending Perl Critic - Customizing is out-of-the-box easy, how do I extend Perl Critic? ... extending Perl Critic is as easy as adding new policy modules ... you can write your own, or grab some pre-written    extensions from CPAN
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Surveying The Land - First, let's see what all policies Perl Critic provides for us ... there are 98 policies that you get in the core distribution ... the policies are all in the Perl::Critic::Policy namespace ... the policies are divided into 16 categories
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Core Policy Categories (1-4) - BuiltinFunctions  ... fun with builtins like ProhibitStringyEval - ClassHierarchies  ... oo rules like ProhibitExplicitISA - CodeLayout  ... picky stuff like RequireTidyCode - ControlStructures  ... control structure rules like ProhibitUnlessBlocks
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Core Policy Categories (5-8) - Documentation ... POD rules like RequirePodAtEnd - ErrorHandling ... the singular RequireCarping - InputOutput ... I/O related like ProhibitTwoArgOpen - Miscellanea ... random pickiness like RequireRcsKeywords
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Core Policy Categories (9-12) - Modules ... module rules like RequireEndWithOne - NamingConventions ... includes MyFavorite ProhibitMixedCaseSubs - References ... the one and only ProhibitDoubleSigils - RegularExpressions ... regex goodness like RequireExtendedFormatting
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Core Policy Categories (13-16) - Subroutines ... subroutine related like RequireFinalReturn - TestingAndDebugging ... tends to be prama-related things like RequireUseStrict - ValuesAndExpressions ... rhs rules such as ProhibitEmptyQuotes - Variables ... variable rules such as ProhibitLocalVars
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Core Policy Categories (the end) - hey, stop complaining, I could have done all 98 :) - so what if these polices aren't enough or just don't fit  your organization? ... use someone else's extensions!
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Perl::Critic::Bangs - a collection of Perl Critic policies written by Andy Lester - readily available on CPAN - adds the following policies: ... ProhibitCommentedOutCode ... because your not really using it and it's in svn anyway ... ProhibitFlagComments ... don't TODO, JFDI ... ProhibitNoPlan ... plan your tests, test your plan
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Perl::Critic::Bangs (cont'd) - and a few more: ... ProhibitNumberedNames ... because $my_variable2 isn't very creative ... ProhibitRefProtoOrProto ... ref($proto) || $proto for determining class name is  typically wrong ... ProhibitVagueNames ... $data, $info, $wtf?  ... is that still not enough for you? The fully qualified name is Perl::Critic::Policy::Bangs::ProhibitNumberedNames
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Perl::Critic::More - then how about more, Chris Dolan's Perl::Critic::More that is: ... CodeLayout::RequireASCII ... no high-bit code characters for you! ... Editor::RequireEmacsFileVariables ... special emacs variables... I'll have to take your word on  this one ... Modules::PerlMinimumVersion ... how backwards-compatible are you? ... Modules::RequirePerlVersion ... use 5.8.0  ... how about one more set?
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Perl::Critic::Lax - is Perl Critic too strict, the try Ricardo Signes's Perl::Critic::Lax: ... ProhibitEmptyQuotes::ExceptAsFallback ... $got || ''; looks too good not to use ... ProhibitStringyEval::ExceptForRequire ... stringy evals are bad and all, but sometimes you just  gotta use them ... RequireEndWithTrueConst ... because sometimes humor is more important ... RequireExplicitPackage::ExceptForPragmata ... because your not always in need of a package, but you  can always use warnings and strict
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 CPAN'd Extensions - we've seen a pretty good mix of Perl Critic extensions that are  available on CPAN: ... Perl::Critic::Bangs ... Perl::Critic::More ... Perl::Critic::Lax ... but these won't always do the trick
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Creating Your Own Policies - Sometimes you just have to warm up the editor and code your  own ... how difficult is it? - It is actually surprisingly easy to create your own policies, you  just need to create a module in the Perl::Critic::Policy namespace that has some required subroutines. ... let's see what it takes
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - We'll start by looking at a core Policy that requires that you use the block form of grep - Here's what it is looking for: @matches = grep  /pattern/,  @list;  #not ok @matches = grep { /pattern/ }  @list;  #ok ... real code please!
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - There's a little administrative overhead: package  Perl::Critic::Policy::BuiltinFunctions::RequireBlockGrep; use strict; use warnings; use Perl::Critic::Utils qw{ :severities :classification :ppi }; use base 'Perl::Critic::Policy'; our $VERSION = 1.051; Declare your package Import some handy utilities Inherit from the core Policy class
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Some information required by Perl Critic: my $desc = q{Expression form of "grep"}; my $expl = [ 169 ]; A description of what you policy does Either a page reference for “Perl Best Practices” or an explaination of what the offending code is doing and instructions on how to fix it.
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Some information required by Perl Critic: sub supported_parameters {  return()  } sub default_severity {  return $SEVERITY_HIGH } * See ControlStructures::ProhibitPostfixControls  for an example Returns a list of constructor parameters that the module supports, in this case none* Returns a numeric value that indicates the default severity for the module.  There are five constants exported from a Perl Critic utility module: $SEVERITY_HIGHEST = 5 $SEVERITY_HIGH  = 4 $SEVERITY_MEDIUM  = 3 $SEVERITY_LOW  = 2 $SEVERITY_LOWEST  = 1 Why these aren't 'brutal' through 'gental' I don't know
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Some information required by Perl Critic: sub default_themes  {  return qw( core bugs pbp )  } sub applies_to  {  return 'PPI::Token::Word'  } Returns a list of default themes that identify this policy; you probably won't be using core Returns a list of PPI package names that the policy is applied to.  Since all of the PPI DOM objects could be potentially analyzed by every Perl Critic policy, this provides a filter that gets passes your policy only the elements that you care about.
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - And now the method that does all of the work: sub violates { my ( $self, $elem, undef ) = @_; return if $elem ne 'grep'; return if ! is_function_call($elem); my $arg = first_arg($elem); return if !$arg; return if $arg->isa('PPI::Structure::Block'); return $self->violation( $desc, $expl, $elem ); } The method is passed the policy object, a PPI document object representing the current element in the code, and the entire PPI document. If a problem is found, the violation method is called with the the policy description,  explanation  of the issue, and offending PPI object as arguments... I guess you can tweak the description and  explanation  if you want.
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Let's take a closer look at the meat of the subroutine: return if $elem ne 'grep'; return if ! is_function_call($elem); We know we are getting PPI::Token::Words, which are subclasses of PPI::Element, which in turn overrides 'ne' to return the actual content of the element... in this case the actual word.  We only want to consider 'grep' is_function_call is one of those handy subroutines exported by Perl::Critic::Utils.  In this case, it does the dirty work involved in determining if a given word is a function call based on the PPI::Token::Word's context in the document.  We only want to consider grep if it is actually the function call to grep.
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Only a little more to go my $arg = first_arg($elem); return if !$arg; return if $arg->isa('PPI::Structure::Block'); first_arg is another one of those Perl Critic utility methods.  In this case, it is plucking the first argument passed to the grep function. If there is no argument, we can't tell if it is null, so assume it's not wrong. Finally we see if the first argument to grep is a block.  If it is, then everything is okay.
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Let's look at the code one more time sub violates { my ( $self, $elem, undef ) = @_; return if $elem ne 'grep'; return if ! is_function_call($elem); my $arg = first_arg($elem); return if !$arg; return if $arg->isa('PPI::Structure::Block'); return $self->violation( $desc, $expl, $elem ); }
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Do you see the basic idea behind the code? ... We try to find every excuse for why the code is not in violation ... are you a grep? ... are you a grep function? ... do you have any arguments? ... is your first argument a block? ... and finally, we return a violation ... innocent until proven guilty ... your code doesn't have to flow this way, but it tends to be a good way to approach the problem
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 What Did We Learn - Building custom policies is pretty easy; it requires: ... a little bit of setup code ... a package name (Perl::Critic::Policy::) ... a description of the policy ... an  explanation  of the issue ... a default set of themes ... a default severity ... a list of PPI elements to consider ... an optional list of accepted constructor arguments ... a violates method to do all of the work ... but this is typically a small amount of work ... most policies can be implemented in tens of lines of  code
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Perl::Critic::Utils and PPI - So what makes policy building tricky? ... working with Perl::Critic::Utils and PPI ... both are easy to use, but it takes some time to remember all of the functionality that they provide
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Perl::Critic::Utils - Provides 33 importable subroutines for analyzing and working  with PPI elements ... some examples: ... is_hash_key ... is_label_pointer ... is_perl_bareword ... is_perl_builtin_with_optional_argument - Provides 21 importable constants ... some examples: ... $COMMA ... $FATCOMMA ... you really just have to RTFM
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 PPI - Provides 62 types of PDOM objects representing pieces of  ... some examples: ... PPI::Document::Fragment ... PPI::Statement::Package ... PPI::Structure::ForLoop ... PPI::Token::Whitespace ... PPI::Token::QuoteLike::Backtick - Any of the PDOM types could be included in your applies_to()  list of elements that you want to consider in your policy ... there are so many of these that you really have to RTFM
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 PPI::Element - Most of the PPI PDOM objects you'll be interested in inherit  from PPI::Element, which provides it's own set of utility  methods to help you poke around the PDOM passed to your  violates() method. ... some examples: ... significant – is the element really significant to the code ... next_sibling – next element in the PDOM ... snext_sibling – same as above, only skips insignificant  elements ... previous_token – previous PPI::Token element - There are a lot of these that let you walk around the code
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Testing Your Policies - Testing policies is actually quite easy also... if you peek into  the Perl Critic source and borrow code from them that is :) - All that you have to do is create a Perl::Critic object and your  policy object and then just run the policy on a suite of code  samples
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Testing Your Policies - First set use some modules and then set up some tests use warnings; use strict; use Test::More; use Perl::Critic; my @to_validate = ( 'grep {}', 'grep { 1 }', 'grip ""', ); my @to_violate = ( 'grep ""', 'grep "1"', ); plan tests => @to_validate + @to_violate; I like setting up pieces of code that I expect to be valid and pieces that I expect to violate my policy And dynamically creating my test plan based on the number of code samples I'm using
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Testing Your Policies - Then create a Perl::Critic object and an object of your policy my $c = Perl::Critic->new( -profile => 'NONE' ); my $policy =  Perl::Critic::Policy::BuiltinFunctions::RequireBlockGrep ->new(); $c->add_policy( -policy => $policy ); Just create the two objects and add your policy as the one-and-only policy
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Testing Your Policies - And finally apply your policy to the code samples ok( ( scalar $c->critique( _ ) == 0 ), 'policy on valid code' ) for (@to_validate); ok( ( scalar $c->critique( _ ) > 0 ), 'policy on invalid code' ) for (@to_violate);
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Testing Your Policies - We have tests! --(0)> prove test.pl  test....ok  All tests successful. Files=1, Tests=6,  1 wallclock secs (  0.86 cusr +  0.18 csys =  1.04 CPU )
Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Questions? Comments? Criticisms?

More Related Content

What's hot

PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentationThanh Robi
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentationnicobn
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDPaweł Michalik
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitMichelangelo van Dam
 
Python Debugging Fundamentals
Python Debugging FundamentalsPython Debugging Fundamentals
Python Debugging Fundamentalscbcunc
 
Unit Testing using PHPUnit
Unit Testing using  PHPUnitUnit Testing using  PHPUnit
Unit Testing using PHPUnitvaruntaliyan
 
Test your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practiceTest your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practiceSebastian Marek
 
Python Testing Fundamentals
Python Testing FundamentalsPython Testing Fundamentals
Python Testing Fundamentalscbcunc
 
PHPUnit: from zero to hero
PHPUnit: from zero to heroPHPUnit: from zero to hero
PHPUnit: from zero to heroJeremy Cook
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmanndpc
 
Test Driven Development with PHPUnit
Test Driven Development with PHPUnitTest Driven Development with PHPUnit
Test Driven Development with PHPUnitMindfire Solutions
 
PhpUnit Best Practices
PhpUnit Best PracticesPhpUnit Best Practices
PhpUnit Best PracticesEdorian
 
Keep your repo clean
Keep your repo cleanKeep your repo clean
Keep your repo cleanHector Canto
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策kwatch
 
Unit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step TrainingUnit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step TrainingRam Awadh Prasad, PMP
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummiesHarry Potter
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitMichelangelo van Dam
 
Test in action – week 1
Test in action – week 1Test in action – week 1
Test in action – week 1Yi-Huan Chan
 

What's hot (20)

PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
 
PHPUnit
PHPUnitPHPUnit
PHPUnit
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentation
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Python Debugging Fundamentals
Python Debugging FundamentalsPython Debugging Fundamentals
Python Debugging Fundamentals
 
Unit Testing using PHPUnit
Unit Testing using  PHPUnitUnit Testing using  PHPUnit
Unit Testing using PHPUnit
 
Test your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practiceTest your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practice
 
Python Testing Fundamentals
Python Testing FundamentalsPython Testing Fundamentals
Python Testing Fundamentals
 
PHPUnit: from zero to hero
PHPUnit: from zero to heroPHPUnit: from zero to hero
PHPUnit: from zero to hero
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmann
 
Test Driven Development with PHPUnit
Test Driven Development with PHPUnitTest Driven Development with PHPUnit
Test Driven Development with PHPUnit
 
PhpUnit Best Practices
PhpUnit Best PracticesPhpUnit Best Practices
PhpUnit Best Practices
 
Keep your repo clean
Keep your repo cleanKeep your repo clean
Keep your repo clean
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
 
Unit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step TrainingUnit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step Training
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummies
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnit
 
Phpunit testing
Phpunit testingPhpunit testing
Phpunit testing
 
Test in action – week 1
Test in action – week 1Test in action – week 1
Test in action – week 1
 

Similar to Extending Perl Critic

Packaging perl (LPW2010)
Packaging perl (LPW2010)Packaging perl (LPW2010)
Packaging perl (LPW2010)p3castro
 
Managing Perl Installations: A SysAdmin's View
Managing Perl Installations: A SysAdmin's ViewManaging Perl Installations: A SysAdmin's View
Managing Perl Installations: A SysAdmin's ViewBaden Hughes
 
Packaging for the Maemo Platform
Packaging for the Maemo PlatformPackaging for the Maemo Platform
Packaging for the Maemo PlatformJeremiah Foster
 
30 Minutes To CPAN
30 Minutes To CPAN30 Minutes To CPAN
30 Minutes To CPANdaoswald
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet CampPuppet
 
Php Best Practices
Php Best PracticesPhp Best Practices
Php Best PracticesAnsar Ahmed
 
Php Best Practices
Php Best PracticesPhp Best Practices
Php Best PracticesAnsar Ahmed
 
Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013Brian Sam-Bodden
 
Aspect-oriented programming in Perl
Aspect-oriented programming in PerlAspect-oriented programming in Perl
Aspect-oriented programming in Perlmegakott
 
Perl Tidy Perl Critic
Perl Tidy Perl CriticPerl Tidy Perl Critic
Perl Tidy Perl Criticolegmmiller
 
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010singingfish
 
Puppet Camp Paris 2014: Test Driven Development
Puppet Camp Paris 2014: Test Driven DevelopmentPuppet Camp Paris 2014: Test Driven Development
Puppet Camp Paris 2014: Test Driven DevelopmentPuppet
 
20140408 tdd puppetcamp-paris
20140408 tdd puppetcamp-paris20140408 tdd puppetcamp-paris
20140408 tdd puppetcamp-parisJohan De Wit
 
PBX on a non-specialized distro
PBX on a non-specialized distroPBX on a non-specialized distro
PBX on a non-specialized distroStefanoFancello
 
Automated Puppet Testing - PuppetCamp Chicago '12 - Scott Nottingham
Automated Puppet Testing - PuppetCamp Chicago '12 - Scott NottinghamAutomated Puppet Testing - PuppetCamp Chicago '12 - Scott Nottingham
Automated Puppet Testing - PuppetCamp Chicago '12 - Scott NottinghamPuppet
 
Puppet camp chicago-automated_testing2
Puppet camp chicago-automated_testing2Puppet camp chicago-automated_testing2
Puppet camp chicago-automated_testing2nottings
 

Similar to Extending Perl Critic (20)

Packaging perl (LPW2010)
Packaging perl (LPW2010)Packaging perl (LPW2010)
Packaging perl (LPW2010)
 
Managing Perl Installations: A SysAdmin's View
Managing Perl Installations: A SysAdmin's ViewManaging Perl Installations: A SysAdmin's View
Managing Perl Installations: A SysAdmin's View
 
Packaging for the Maemo Platform
Packaging for the Maemo PlatformPackaging for the Maemo Platform
Packaging for the Maemo Platform
 
30 Minutes To CPAN
30 Minutes To CPAN30 Minutes To CPAN
30 Minutes To CPAN
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
 
Perl 20tips
Perl 20tipsPerl 20tips
Perl 20tips
 
Php Best Practices
Php Best PracticesPhp Best Practices
Php Best Practices
 
Php Best Practices
Php Best PracticesPhp Best Practices
Php Best Practices
 
Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013
 
Perlbrew
PerlbrewPerlbrew
Perlbrew
 
Unit Testing Lots of Perl
Unit Testing Lots of PerlUnit Testing Lots of Perl
Unit Testing Lots of Perl
 
Aspect-oriented programming in Perl
Aspect-oriented programming in PerlAspect-oriented programming in Perl
Aspect-oriented programming in Perl
 
Perl Tidy Perl Critic
Perl Tidy Perl CriticPerl Tidy Perl Critic
Perl Tidy Perl Critic
 
Coding standard
Coding standardCoding standard
Coding standard
 
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
 
Puppet Camp Paris 2014: Test Driven Development
Puppet Camp Paris 2014: Test Driven DevelopmentPuppet Camp Paris 2014: Test Driven Development
Puppet Camp Paris 2014: Test Driven Development
 
20140408 tdd puppetcamp-paris
20140408 tdd puppetcamp-paris20140408 tdd puppetcamp-paris
20140408 tdd puppetcamp-paris
 
PBX on a non-specialized distro
PBX on a non-specialized distroPBX on a non-specialized distro
PBX on a non-specialized distro
 
Automated Puppet Testing - PuppetCamp Chicago '12 - Scott Nottingham
Automated Puppet Testing - PuppetCamp Chicago '12 - Scott NottinghamAutomated Puppet Testing - PuppetCamp Chicago '12 - Scott Nottingham
Automated Puppet Testing - PuppetCamp Chicago '12 - Scott Nottingham
 
Puppet camp chicago-automated_testing2
Puppet camp chicago-automated_testing2Puppet camp chicago-automated_testing2
Puppet camp chicago-automated_testing2
 

More from joshua.mcadams

Open Flash Chart And Perl
Open Flash Chart And PerlOpen Flash Chart And Perl
Open Flash Chart And Perljoshua.mcadams
 
Introduction To Testing With Perl
Introduction To Testing With PerlIntroduction To Testing With Perl
Introduction To Testing With Perljoshua.mcadams
 
Thank A Cpan Contributor Today
Thank A Cpan Contributor TodayThank A Cpan Contributor Today
Thank A Cpan Contributor Todayjoshua.mcadams
 
Utility Modules That You Should Know About
Utility Modules That You Should Know AboutUtility Modules That You Should Know About
Utility Modules That You Should Know Aboutjoshua.mcadams
 
YAPC::NA 2007 - Epic Perl Coding
YAPC::NA 2007 - Epic Perl CodingYAPC::NA 2007 - Epic Perl Coding
YAPC::NA 2007 - Epic Perl Codingjoshua.mcadams
 
Lightning Talk: An Introduction To Scrum
Lightning Talk: An Introduction To ScrumLightning Talk: An Introduction To Scrum
Lightning Talk: An Introduction To Scrumjoshua.mcadams
 

More from joshua.mcadams (6)

Open Flash Chart And Perl
Open Flash Chart And PerlOpen Flash Chart And Perl
Open Flash Chart And Perl
 
Introduction To Testing With Perl
Introduction To Testing With PerlIntroduction To Testing With Perl
Introduction To Testing With Perl
 
Thank A Cpan Contributor Today
Thank A Cpan Contributor TodayThank A Cpan Contributor Today
Thank A Cpan Contributor Today
 
Utility Modules That You Should Know About
Utility Modules That You Should Know AboutUtility Modules That You Should Know About
Utility Modules That You Should Know About
 
YAPC::NA 2007 - Epic Perl Coding
YAPC::NA 2007 - Epic Perl CodingYAPC::NA 2007 - Epic Perl Coding
YAPC::NA 2007 - Epic Perl Coding
 
Lightning Talk: An Introduction To Scrum
Lightning Talk: An Introduction To ScrumLightning Talk: An Introduction To Scrum
Lightning Talk: An Introduction To Scrum
 

Recently uploaded

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 

Recently uploaded (20)

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 

Extending Perl Critic

  • 1. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Customizing and Extending Perl Critic Josh McAdams
  • 2. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 A Quick Review - What is Perl Critic ... a static source code analyzer for Perl code ... a system of policies that are enforced on your code ... written by Jeffrey Ryan Thalhammer #!/usr/bin/perl print “Hallo, Denmark”;
  • 3. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 A Quick Review --(0)> perlcritic hello_denmark.pl Code before strictures are enabled at line 3, column 1. See page 429 of PBP. (Severity: 5) ... is the jarring your memory? Running perlcritic...
  • 4. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Customizing Perl Critic - How do you customize Perl Critic ... we saw much of this in the “Introduction” talk ... you can ... ignore policies ... assign new severities to policies ... group policies into themes ... pass constructor arguments to policies
  • 5. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Customizing Perl Critic --(0)> cat ~/.perlcriticrc severity = 2 top = 5 exclude = Editor::RequireEmacsFileVariables Miscellanea::RequireRcsKeywords [ControlStructures::ProhibitPostfixControls] severity = 4 allow = if unless theme = iffy Looking into a .perlcriticrc file... ... but what about extending Perl Critic? The default severity to report How many violations to report Policies to ignore Change the default severity for a policy Pass arguments to the policy constructor, in this case telling it to allow trailing ifs and unlesses Apply a new theme
  • 6. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Extending Perl Critic - Customizing is out-of-the-box easy, how do I extend Perl Critic? ... extending Perl Critic is as easy as adding new policy modules ... you can write your own, or grab some pre-written extensions from CPAN
  • 7. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Surveying The Land - First, let's see what all policies Perl Critic provides for us ... there are 98 policies that you get in the core distribution ... the policies are all in the Perl::Critic::Policy namespace ... the policies are divided into 16 categories
  • 8. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Core Policy Categories (1-4) - BuiltinFunctions ... fun with builtins like ProhibitStringyEval - ClassHierarchies ... oo rules like ProhibitExplicitISA - CodeLayout ... picky stuff like RequireTidyCode - ControlStructures ... control structure rules like ProhibitUnlessBlocks
  • 9. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Core Policy Categories (5-8) - Documentation ... POD rules like RequirePodAtEnd - ErrorHandling ... the singular RequireCarping - InputOutput ... I/O related like ProhibitTwoArgOpen - Miscellanea ... random pickiness like RequireRcsKeywords
  • 10. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Core Policy Categories (9-12) - Modules ... module rules like RequireEndWithOne - NamingConventions ... includes MyFavorite ProhibitMixedCaseSubs - References ... the one and only ProhibitDoubleSigils - RegularExpressions ... regex goodness like RequireExtendedFormatting
  • 11. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Core Policy Categories (13-16) - Subroutines ... subroutine related like RequireFinalReturn - TestingAndDebugging ... tends to be prama-related things like RequireUseStrict - ValuesAndExpressions ... rhs rules such as ProhibitEmptyQuotes - Variables ... variable rules such as ProhibitLocalVars
  • 12. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Core Policy Categories (the end) - hey, stop complaining, I could have done all 98 :) - so what if these polices aren't enough or just don't fit your organization? ... use someone else's extensions!
  • 13. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Perl::Critic::Bangs - a collection of Perl Critic policies written by Andy Lester - readily available on CPAN - adds the following policies: ... ProhibitCommentedOutCode ... because your not really using it and it's in svn anyway ... ProhibitFlagComments ... don't TODO, JFDI ... ProhibitNoPlan ... plan your tests, test your plan
  • 14. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Perl::Critic::Bangs (cont'd) - and a few more: ... ProhibitNumberedNames ... because $my_variable2 isn't very creative ... ProhibitRefProtoOrProto ... ref($proto) || $proto for determining class name is typically wrong ... ProhibitVagueNames ... $data, $info, $wtf? ... is that still not enough for you? The fully qualified name is Perl::Critic::Policy::Bangs::ProhibitNumberedNames
  • 15. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Perl::Critic::More - then how about more, Chris Dolan's Perl::Critic::More that is: ... CodeLayout::RequireASCII ... no high-bit code characters for you! ... Editor::RequireEmacsFileVariables ... special emacs variables... I'll have to take your word on this one ... Modules::PerlMinimumVersion ... how backwards-compatible are you? ... Modules::RequirePerlVersion ... use 5.8.0 ... how about one more set?
  • 16. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Perl::Critic::Lax - is Perl Critic too strict, the try Ricardo Signes's Perl::Critic::Lax: ... ProhibitEmptyQuotes::ExceptAsFallback ... $got || ''; looks too good not to use ... ProhibitStringyEval::ExceptForRequire ... stringy evals are bad and all, but sometimes you just gotta use them ... RequireEndWithTrueConst ... because sometimes humor is more important ... RequireExplicitPackage::ExceptForPragmata ... because your not always in need of a package, but you can always use warnings and strict
  • 17. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 CPAN'd Extensions - we've seen a pretty good mix of Perl Critic extensions that are available on CPAN: ... Perl::Critic::Bangs ... Perl::Critic::More ... Perl::Critic::Lax ... but these won't always do the trick
  • 18. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Creating Your Own Policies - Sometimes you just have to warm up the editor and code your own ... how difficult is it? - It is actually surprisingly easy to create your own policies, you just need to create a module in the Perl::Critic::Policy namespace that has some required subroutines. ... let's see what it takes
  • 19. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - We'll start by looking at a core Policy that requires that you use the block form of grep - Here's what it is looking for: @matches = grep /pattern/, @list; #not ok @matches = grep { /pattern/ } @list; #ok ... real code please!
  • 20. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - There's a little administrative overhead: package Perl::Critic::Policy::BuiltinFunctions::RequireBlockGrep; use strict; use warnings; use Perl::Critic::Utils qw{ :severities :classification :ppi }; use base 'Perl::Critic::Policy'; our $VERSION = 1.051; Declare your package Import some handy utilities Inherit from the core Policy class
  • 21. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Some information required by Perl Critic: my $desc = q{Expression form of "grep"}; my $expl = [ 169 ]; A description of what you policy does Either a page reference for “Perl Best Practices” or an explaination of what the offending code is doing and instructions on how to fix it.
  • 22. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Some information required by Perl Critic: sub supported_parameters { return() } sub default_severity { return $SEVERITY_HIGH } * See ControlStructures::ProhibitPostfixControls for an example Returns a list of constructor parameters that the module supports, in this case none* Returns a numeric value that indicates the default severity for the module. There are five constants exported from a Perl Critic utility module: $SEVERITY_HIGHEST = 5 $SEVERITY_HIGH = 4 $SEVERITY_MEDIUM = 3 $SEVERITY_LOW = 2 $SEVERITY_LOWEST = 1 Why these aren't 'brutal' through 'gental' I don't know
  • 23. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Some information required by Perl Critic: sub default_themes { return qw( core bugs pbp ) } sub applies_to { return 'PPI::Token::Word' } Returns a list of default themes that identify this policy; you probably won't be using core Returns a list of PPI package names that the policy is applied to. Since all of the PPI DOM objects could be potentially analyzed by every Perl Critic policy, this provides a filter that gets passes your policy only the elements that you care about.
  • 24. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - And now the method that does all of the work: sub violates { my ( $self, $elem, undef ) = @_; return if $elem ne 'grep'; return if ! is_function_call($elem); my $arg = first_arg($elem); return if !$arg; return if $arg->isa('PPI::Structure::Block'); return $self->violation( $desc, $expl, $elem ); } The method is passed the policy object, a PPI document object representing the current element in the code, and the entire PPI document. If a problem is found, the violation method is called with the the policy description, explanation of the issue, and offending PPI object as arguments... I guess you can tweak the description and explanation if you want.
  • 25. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Let's take a closer look at the meat of the subroutine: return if $elem ne 'grep'; return if ! is_function_call($elem); We know we are getting PPI::Token::Words, which are subclasses of PPI::Element, which in turn overrides 'ne' to return the actual content of the element... in this case the actual word. We only want to consider 'grep' is_function_call is one of those handy subroutines exported by Perl::Critic::Utils. In this case, it does the dirty work involved in determining if a given word is a function call based on the PPI::Token::Word's context in the document. We only want to consider grep if it is actually the function call to grep.
  • 26. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Only a little more to go my $arg = first_arg($elem); return if !$arg; return if $arg->isa('PPI::Structure::Block'); first_arg is another one of those Perl Critic utility methods. In this case, it is plucking the first argument passed to the grep function. If there is no argument, we can't tell if it is null, so assume it's not wrong. Finally we see if the first argument to grep is a block. If it is, then everything is okay.
  • 27. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Let's look at the code one more time sub violates { my ( $self, $elem, undef ) = @_; return if $elem ne 'grep'; return if ! is_function_call($elem); my $arg = first_arg($elem); return if !$arg; return if $arg->isa('PPI::Structure::Block'); return $self->violation( $desc, $expl, $elem ); }
  • 28. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 BuiltinFunctions::RequireBlockGrep - Do you see the basic idea behind the code? ... We try to find every excuse for why the code is not in violation ... are you a grep? ... are you a grep function? ... do you have any arguments? ... is your first argument a block? ... and finally, we return a violation ... innocent until proven guilty ... your code doesn't have to flow this way, but it tends to be a good way to approach the problem
  • 29. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 What Did We Learn - Building custom policies is pretty easy; it requires: ... a little bit of setup code ... a package name (Perl::Critic::Policy::) ... a description of the policy ... an explanation of the issue ... a default set of themes ... a default severity ... a list of PPI elements to consider ... an optional list of accepted constructor arguments ... a violates method to do all of the work ... but this is typically a small amount of work ... most policies can be implemented in tens of lines of code
  • 30. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Perl::Critic::Utils and PPI - So what makes policy building tricky? ... working with Perl::Critic::Utils and PPI ... both are easy to use, but it takes some time to remember all of the functionality that they provide
  • 31. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Perl::Critic::Utils - Provides 33 importable subroutines for analyzing and working with PPI elements ... some examples: ... is_hash_key ... is_label_pointer ... is_perl_bareword ... is_perl_builtin_with_optional_argument - Provides 21 importable constants ... some examples: ... $COMMA ... $FATCOMMA ... you really just have to RTFM
  • 32. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 PPI - Provides 62 types of PDOM objects representing pieces of ... some examples: ... PPI::Document::Fragment ... PPI::Statement::Package ... PPI::Structure::ForLoop ... PPI::Token::Whitespace ... PPI::Token::QuoteLike::Backtick - Any of the PDOM types could be included in your applies_to() list of elements that you want to consider in your policy ... there are so many of these that you really have to RTFM
  • 33. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 PPI::Element - Most of the PPI PDOM objects you'll be interested in inherit from PPI::Element, which provides it's own set of utility methods to help you poke around the PDOM passed to your violates() method. ... some examples: ... significant – is the element really significant to the code ... next_sibling – next element in the PDOM ... snext_sibling – same as above, only skips insignificant elements ... previous_token – previous PPI::Token element - There are a lot of these that let you walk around the code
  • 34. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Testing Your Policies - Testing policies is actually quite easy also... if you peek into the Perl Critic source and borrow code from them that is :) - All that you have to do is create a Perl::Critic object and your policy object and then just run the policy on a suite of code samples
  • 35. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Testing Your Policies - First set use some modules and then set up some tests use warnings; use strict; use Test::More; use Perl::Critic; my @to_validate = ( 'grep {}', 'grep { 1 }', 'grip ""', ); my @to_violate = ( 'grep ""', 'grep "1"', ); plan tests => @to_validate + @to_violate; I like setting up pieces of code that I expect to be valid and pieces that I expect to violate my policy And dynamically creating my test plan based on the number of code samples I'm using
  • 36. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Testing Your Policies - Then create a Perl::Critic object and an object of your policy my $c = Perl::Critic->new( -profile => 'NONE' ); my $policy = Perl::Critic::Policy::BuiltinFunctions::RequireBlockGrep ->new(); $c->add_policy( -policy => $policy ); Just create the two objects and add your policy as the one-and-only policy
  • 37. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Testing Your Policies - And finally apply your policy to the code samples ok( ( scalar $c->critique( _ ) == 0 ), 'policy on valid code' ) for (@to_validate); ok( ( scalar $c->critique( _ ) > 0 ), 'policy on invalid code' ) for (@to_violate);
  • 38. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Testing Your Policies - We have tests! --(0)> prove test.pl test....ok All tests successful. Files=1, Tests=6, 1 wallclock secs ( 0.86 cusr + 0.18 csys = 1.04 CPU )
  • 39. Customizing and Extending Perl Critic Nordic Perl Workshop 2007 Questions? Comments? Criticisms?