Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Perl-Critic CPAN distribution.

Report information
The Basics
Id: 56625
Status: resolved
Priority: 0/
Queue: Perl-Critic

People
Owner: Nobody in particular
Requestors: JARIAALTO [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: Close filehandles as soon as possible after opening (possibly false positive)
MULTIPLE FALSE POSITIVES Close filehandles as soon as possible after opening them at line 8, column 5. See page 209 of PBP. 3 is not one of the allowed literal values (0, 1, 2). Use the Readonly module or the "constant" pragma instead at line 30, column 16. Unnamed numeric literals make code less maintainable. 4 is not one of the allowed literal values (0, 1, 2). Use the Readonly module or the "constant" pragma instead at line 30, column 19. Unnamed numeric literals make code less maintainable. 5 is not one of the allowed literal values (0, 1, 2). Use the Readonly module or the "constant" pragma instead at line 30, column 22. Unnamed numeric literals make code less maintainable. [An excerpt, not runnable "as is"] 1 #!/usr/bin/perl 2 use strict; 3 4 sub Read ($) 5 { 6 my $file = shift; 7 8 open my $FH, "<", $file or return; 9 10 my (%tabs, %div); 11 12 while ( <$FH> ) 13 { 14 chomp; 15 16 if ( /^([[:space:]]+)/ ) 17 { 18 my $len = length TabToSpaces $1; 19 20 $tabs{$len}++; 21 $TABS{$len}++; 22 23 if ( $len == 2 ) 24 { 25 $div{2}++; 26 $DIV{2}++; 27 } 28 elsif ( $len > 2 and $len <= $INDENT_MAX) 29 { 30 for my $div (3, 4, 5) 31 { 32 unless ( $len % $div ) 33 { 34 $div{$div}++; 35 $DIV{$div}++; 36 last; 37 } 38 } 39 } 40 } 41 } 42 43 close $FH or warn "Close failure $ERRNO"; 44 45 if ( $verb == 1 ) 46 { 47 print $file, "\n"; 48 } 49 elsif ( $verb > 1 ) 50 { 51 Print \%tabs, "$file BY INDENT"; 52 Print \%div, "$file BY INDENTATION LEVEL (multiples of)"; 53 } 54 }
Subject: Close filehandles as soon as possible after opening them (false positive)
FALSE POSITIVE; close() is called Close filehandles as soon as possible after opening them at line 8, column 14. See page 209 of PBP. [An excerpt, not necessarily runnable "as is"] 1 #!/usr/bin/perl 2 use strict; 3 4 for my $file ( @files ) 5 { 6 my $FILE; 7 8 unless ( open my $FILE, "<", $file ) 9 { 10 warn "ERROR: cannot open"; 11 next; 12 } 13 else 14 { 15 binmode $FILE; 16 local $INPUT_RECORD_SEPARATOR = undef; 17 $ARG = <$FILE>; 18 close $FILE or warn "Close $file error $ERRNO"; 19 } 20 }
Subject: Re: [rt.cpan.org #56625] Close filehandles as soon as possible after opening (possibly false positive)
Date: Thu, 15 Apr 2010 08:06:05 -0500
To: bug-Perl-Critic [...] rt.cpan.org
From: Elliot Shank <perl [...] galumph.com>
These are all true positives.
On Thu Apr 15 09:06:21 2010, clonezone wrote: Show quoted text
> These are all true positives.
I don't understand: Close filehandles as soon as possible after opening them at line 8, The file is closed as soon as porocessed after a simple loop.
On Thu Apr 15 09:10:19 2010, JARIAALTO wrote: Show quoted text
> On Thu Apr 15 09:06:21 2010, clonezone wrote:
> > These are all true positives.
> > I don't understand: > > Close filehandles as soon as possible after opening them at line 8, > > The file is closed as soon as porocessed after a simple loop.
I suspect the problem is the phrase "as soon as possible." This is a Perl Best Practices policy, and I suspect the message emitted by the policy describes better what Perl Best Practices says than how the policy is implemented. If you take "as soon as possible" to mean "as soon as whatever processing the file needs is done," the policy does not do this; in fact, I know of no way to implement that, in any language, without being able to read the programmer's mind. As I think the documentation in Perl::Critic::Policy::InputOutput::RequireBriefOpen makes clear, the issue being addressed is potential file handle leaks. The farther the "close" is away from the "open", the more likely a leak becomes. You have quite properly used lexical variables rather than Perl file handles -- that is, "my $fh; open $fh, '<', 'file'" rather than "open FH, '<', 'file'". This helps some, but does not completely eliminate the problem. Perhaps the violation message could say this better, but I have been unable to come up with a one-line message I think is an improvement. So no, the point of this policy is not to allow you 3000 statements between an open and a close if that is what it "really" takes to process the file. The point is to flag all instances where the close is more than a certain distance away from the open. And it does this. If you do not like what it does, you have a number of options: * Configure the policy to allow more distance between the open and the close. * Annotate the open with a '## no critic (RequireBriefOpen)', to tell Perl::Critic to ignore this particular open. * Hide the open in some way. The documentation gives a couple ways to do this. * Disable the policy if it does not do what you want. Most of these options apply to all Perl::Critic policies. The exception is the "Configure" option, since not all policies are configurable.
See RT 56625, same subject.
This ticket was kept open because of the suspicion that the second example provided would fail even if the line constraint was met, and with the intention of working on it at the same time as RT #64437. Well, it appears that, if the line number constraint is met, the suspect code is in fact compliant. So I am closing this ticket.