>." />

Perl::Critic::Policy::InputOutput::ProhibitTwoArgOpen - Write C<< open $fh, q{<}, $filename; >> instead of C<< open $fh, "<$filename"; >>.


Perl-Critic documentation Contained in the Perl-Critic distribution.

Index


Code Index:

NAME

Top

Perl::Critic::Policy::InputOutput::ProhibitTwoArgOpen - Write open $fh, q{<}, $filename; instead of open $fh, "<$filename";.

AFFILIATION

Top

This Policy is part of the core Perl::Critic distribution.

DESCRIPTION

Top

The three-argument form of open (introduced in Perl 5.6) prevents subtle bugs that occur when the filename starts with funny characters like '>' or '<'. The IO::File module provides a nice object-oriented interface to filehandles, which I think is more elegant anyway.

  open( $fh, '>output.txt' );          # not ok
  open( $fh, q{>}, 'output.txt' );     # ok

  use IO::File;
  my $fh = IO::File->new( 'output.txt', q{>} ); # even better!

It's also more explicitly clear to define the input mode of the file, as in the difference between these two:

  open( $fh, 'foo.txt' );       # BAD: Reader must think what default mode is
  open( $fh, '<', 'foo.txt' );  # GOOD: Reader can see open mode

This policy will not complain if the file explicitly states that it is compatible with a version of perl prior to 5.6 via an include statement, e.g. by having require 5.005 in it.

CONFIGURATION

Top

This Policy is not configurable except for the standard options.

NOTES

Top

There are two cases in which you are forced to use the two-argument form of open. When re-opening STDIN, STDOUT, or STDERR, and when doing a safe pipe open, as described in perlipc (perlipc).

SEE ALSO

Top

IO::Handle

IO::File

AUTHOR

Top

Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>

COPYRIGHT

Top


Perl-Critic documentation Contained in the Perl-Critic distribution.

##############################################################################
#      $URL: http://perlcritic.tigris.org/svn/perlcritic/trunk/distributions/Perl-Critic/lib/Perl/Critic/Policy/InputOutput/ProhibitTwoArgOpen.pm $
#     $Date: 2011-05-15 16:34:46 -0500 (Sun, 15 May 2011) $
#   $Author: clonezone $
# $Revision: 4078 $
##############################################################################

package Perl::Critic::Policy::InputOutput::ProhibitTwoArgOpen;

use 5.006001;
use strict;
use warnings;

use Readonly;

use version;

use Perl::Critic::Utils qw{ :severities :classification :ppi };
use base 'Perl::Critic::Policy';

our $VERSION = '1.116';

#-----------------------------------------------------------------------------

Readonly::Scalar my $STDIO_HANDLES_RX => qr/\b STD (?: IN | OUT | ERR \b)/xms;
Readonly::Scalar my $FORK_HANDLES_RX => qr/\A (?: -[|] | [|]- ) \z/xms;
Readonly::Scalar my $DESC => q{Two-argument "open" used};
Readonly::Scalar my $EXPL => [ 207 ];

Readonly::Scalar my $MINIMUM_VERSION => version->new(5.006);

#-----------------------------------------------------------------------------

sub supported_parameters { return ()                         }
sub default_severity     { return $SEVERITY_HIGHEST          }
sub default_themes       { return qw(core pbp bugs security) }
sub applies_to           { return 'PPI::Token::Word'         }

#-----------------------------------------------------------------------------

sub violates {
    my ($self, $elem, $document) = @_;

    return if $elem ne 'open';
    return if ! is_function_call($elem);

    my $version = $document->highest_explicit_perl_version();
    return if $version and $version < $MINIMUM_VERSION;

    my @args = parse_arg_list($elem);

    if ( scalar @args == 2 ) {
        # When opening STDIN, STDOUT, or STDERR, the
        # two-arg form is the only option you have.
        return if $args[1]->[0] =~ $STDIO_HANDLES_RX;
        return if $args[1]->[0]->isa( 'PPI::Token::Quote' )
               && $args[1]->[0]->string() =~ $FORK_HANDLES_RX;
        return $self->violation( $DESC, $EXPL, $elem );
    }

    return; # ok!
}

1;

__END__

#-----------------------------------------------------------------------------

# Local Variables:
#   mode: cperl
#   cperl-indent-level: 4
#   fill-column: 78
#   indent-tabs-mode: nil
#   c-indentation-style: bsd
# End:
# ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :