| Perl-Critic documentation | Contained in the Perl-Critic distribution. |
Perl::Critic::Policy::Objects::ProhibitIndirectSyntax - Prohibit indirect object call syntax.
This Policy is part of the core Perl::Critic distribution.
Indirect object syntax is commonly used in other object-oriented languages for instantiating objects. Perl allows this, but to say that it supports it may be going too far. Instead of writing
my $foo = new Foo;
it is preferable to write
my $foo = Foo->new;
The problem is that Perl needs to make a number of assumptions at compile time to disambiguate the first form, so it tends to be fragile and to produce hard-to-track-down bugs.
Indirect object syntax is also hard for Perl::Critic to disambiguate, so this
policy only checks certain subroutine calls. The names of the subroutines can
be configured using the forbid configuration option:
[Objects::ProhibitIndirectSyntax]
forbid = create destroy
The new subroutine is configured by default; any additional forbid
values are in addition to new.
The general situation can not be handled via static analysis.
Perl::Critic::Policy::Dynamic::NoIndirect and indirect both do a better job with this, but they require that you compile/execute your code.
Thomas R. Wyant, III wyant at cpan dot org
Copyright (c) 2009-2011 Tom Wyant.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. The full text of this license can be found in the LICENSE file included with this module.
| Perl-Critic documentation | Contained in the Perl-Critic distribution. |
############################################################################## # $URL: http://perlcritic.tigris.org/svn/perlcritic/trunk/distributions/Perl-Critic/lib/Perl/Critic/Policy/Objects/ProhibitIndirectSyntax.pm $ # $Date: 2011-05-15 16:34:46 -0500 (Sun, 15 May 2011) $ # $Author: clonezone $ # $Revision: 4078 $ ############################################################################## package Perl::Critic::Policy::Objects::ProhibitIndirectSyntax; use 5.006001; use strict; use warnings; use Carp; use English qw(-no_match_vars); use Perl::Critic::Utils qw{ :severities :classification }; use Readonly; use base 'Perl::Critic::Policy'; our $VERSION = '1.116'; #----------------------------------------------------------------------------- Readonly::Hash my %COMMA => { q<,> => 1, q{=>} => 1, }; Readonly::Scalar my $DOLLAR => q<$>; Readonly::Scalar my $DESC => 'Subroutine "%s" called using indirect syntax'; Readonly::Scalar my $EXPL => [ 349 ]; #----------------------------------------------------------------------------- sub supported_parameters { return ( { name => 'forbid', description => 'Indirect method syntax is forbidden for these methods.', behavior => 'string list', list_always_present_values => [ qw{ new } ], } ) } sub default_severity { return $SEVERITY_HIGH } sub default_themes { return qw( core pbp maintenance ) } sub applies_to { return 'PPI::Token::Word' } #----------------------------------------------------------------------------- sub violates { my ( $self, $elem, $doc ) = @_; # We are only interested in the functions we have been told to check. # Do this before calling is_function_call() because we want to weed # out as many candidate tokens as possible before calling it. return if not $self->{_forbid}->{$elem->content()}; # Make sure it really is a function call. return if not is_function_call($elem); # Per perlobj, it is only an indirect object call if the next sibling # is a word, a scalar symbol, or a block. my $object = $elem->snext_sibling() or return; return if not ( $object->isa( 'PPI::Token::Word' ) or $object->isa( 'PPI::Token::Symbol' ) and $DOLLAR eq $object->raw_type() or $object->isa( 'PPI::Structure::Block' ) ); # Per perlobj, it is not an indirect object call if the operator after # the possible indirect object is a comma. if ( my $operator = $object->snext_sibling() ) { return if $operator->isa( 'PPI::Token::Operator' ) and $COMMA{ $operator->content() }; } my $message = sprintf $DESC, $elem->content(); return $self->violation( $message, $EXPL, $elem ); } 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 :