Provided by: libperl-critic-pulp-perl_99-1_all bug

NAME

       Perl::Critic::Policy::CodeLayout::RequireFinalSemicolon - require a semicolon at the end
       of code blocks

DESCRIPTION

       This policy is part of the "Perl::Critic::Pulp" add-on.  It asks you to put a semicolon
       ";" on the final statement of a subroutine or block.

           sub foo {
             do_something();      # ok
           }

           sub bar {
             do_something()       # bad
           }

       The idea is that if you add more code you don't have to notice the previous line needs a
       terminator.  It's also more like the C language, if you consider that a virtue.

       This is only a matter of style since the code runs the same either way, and on that basis
       this policy is low severity and under the "cosmetic" theme (see "POLICY THEMES" in
       Perl::Critic).

   Same Line Closing Brace
       By default (see "CONFIGURATION" below), a semicolon is not required when the closing brace
       is on the same line as the last statement.  This is good for constants and one-liners.

           sub foo { 'my-constant-value' }     # ok

           sub square { return $_[0] ** 2 }    # ok

   Final Value Expression
       A semicolon is not required in places where the last statement is an expression giving a
       value.

           map { some_thing();
                 $_+123             # ok
               } @values;

           do {
             foo();
             1+2+3                  # ok
           }

       This currently means

           do grep map sort                         # builtins

           reduce any all none notall first         # List::Util
           pairfirst pairgrep pairmap

           mapp map_pairwise grepp grep_pairwise    # List::Pairwise
           firstp first_pairwise lastp last_pairwise

       These module function names are always treated as expressions.  There's no check for
       whether the respective module is actually in use.  Fully qualified names like
       "List::Util::first" are recognised too.

       "do {} while" or "do {} until" loops are ordinary blocks, not expression blocks, so still
       require a semicolon on the last statement inside.

           do {
             foo()                  # bad
           } until ($condition);

   Try/Catch Blocks
       The "Try", "TryCatch" and "Syntax::Feature::Try" modules all add "try" block forms.  These
       are blocks not requiring a terminating semicolon, the same as an "if" etc doesn't.

           use TryCatch;
           sub foo {
             try {
                 attempt_something();
             } catch {
                 error_recovery();
             } # ok, no semi required here for TryCatch
           }

       The insides of the "try" and "catch" are the same as other blocks, but the "try" statement
       itself doesn't require a semicolon.  (See policy
       "ValuesAndExpressions::ProhibitNullStatements" to notice one added unnecessarily.)

       For reference, "PPI" doesn't know "try"/"catch" specifically, so when they don't have a
       final semicolon the next statement runs together and the nature of those parts might be
       lost.  This could upset things like recognition of "for" loops and could potentially make
       some perlcritic reports go wrong.

       The "try"/"catch" block exemption here is only for the modules with this block syntax.
       There are other try modules such as "Try::Tiny" and friends where a final semicolon is
       normal and necessary if more code follows (because their "try" and "catch" are ordinary
       function calls prototyped to take code blocks).

           use Try::Tiny;
           sub foo {
             try {
                 attempt_something();
             } catch {
                 error_recovery();
             } # bad, semi required here for Try::Tiny
           }

   Disabling
       If you don't care about this you can always disable from your .perlcriticrc file in the
       usual way (see "CONFIGURATION" in Perl::Critic),

           [-CodeLayout::RequireFinalSemicolon]

CONFIGURATION

       "except_same_line" (boolean, default true)
           If true (the default) then don't demand a semicolon if the closing brace is on the
           same line as the final statement.

               sub foo { return 123 }     # ok  if "except_same_line=yes"
                                          # bad if "except_same_line=no"

       "except_expression_blocks" (boolean, default true)
           If true (the default) then don't demand a semicolon at the end of an expression block,
           as described under "Final Value Expression" above.

               # ok under "except_expression_blocks=yes"
               # bad under "except_expression_blocks=no"
               do { 1+2+3 }
               map { $_+1 } @array
               grep {defined} @x

           The statements and functions for this exception are currently hard coded.  Maybe in
           the future they could be configurable, though multi-line expressions in this sort of
           thing tends to be unusual anyway.  (See policy
           "BuiltinFunctions::RequireSimpleSortBlock" for example to demand "sort" is only one
           line.)

BUGS

       It's very difficult to distinguish a code block from an anonymous hashref constructor if
       there might be a function prototype in force, eg.

           foo { abc => 123 };   # hash ref normally
                                 # code block if foo() has prototype

       "PPI" tends to assume code.  "RequireFinalSemicolon" currently assumes hashref so as to
       avoid false violations.  Any "try", "catch" or "finally" are presumed to be code blocks
       (the various Try modules).  Perhaps other common or particular functions or syntax with
       code blocks could be recognised.  In general this sort of ambiguity is another good reason
       to avoid function prototypes.

       PPI as of its version 1.270 sometimes takes hashrefs in lists and arrarefs to be code
       blocks, eg.

           ppidump 'foo({%y,x=>1})'
           ppidump '[{%y,x=>1}]'

           ppidump '[{x=>1,%y}]'       # ok, hash

SEE ALSO

       Perl::Critic::Pulp, Perl::Critic, Perl::Critic::Policy::CodeLayout::RequireTrailingCommas,
       Perl::Critic::Policy::CodeLayout::RequireTrailingCommaAtNewline,
       Perl::Critic::Policy::Subroutines::RequireFinalReturn,
       Perl::Critic::Policy::ValuesAndExpressions::ProhibitNullStatements,
       Perl::Critic::Policy::BuiltinFunctions::RequireSimpleSortBlock

       List::Util, List::Pairwise, Try, TryCatch, Syntax::Feature::Try

HOME PAGE

       <http://user42.tuxfamily.org/perl-critic-pulp/index.html>

COPYRIGHT

       Copyright 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, 2021 Kevin Ryde

       Perl-Critic-Pulp is free software; you can redistribute it and/or modify it under the
       terms of the GNU General Public License as published by the Free Software Foundation;
       either version 3, or (at your option) any later version.

       Perl-Critic-Pulp is distributed in the hope that it will be useful, but WITHOUT ANY
       WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
       PURPOSE.  See the GNU General Public License for more details.

       You should have received a copy of the GNU General Public License along with Perl-Critic-
       Pulp.  If not, see <http://www.gnu.org/licenses>.

perl v5.32.1                         Perl::Critic::Policy::CodeLayout::RequireFinalSemicolon(3pm)