Acme::PlayCode - Code transforming to avoid typical typing mistakes


Acme-PlayCode documentation Contained in the Acme-PlayCode distribution.

Index


Code Index:

NAME

Top

Acme::PlayCode - Code transforming to avoid typical typing mistakes

SYNOPSIS

Top

    use Acme::PlayCode;

    my $app = new Acme::PlayCode;

    $app->load_plugin('DoubleToSingle');
    $app->load_plugin('ExchangeCondition');

    my $played_code = $app->play( $code );
    # or
    my $played_code = $app->play( $filename );
    # or
    $app->play( $filename, { rewrite_file => 1 } ); # override $filename with played code

ALPHA WARNING

Top

Acme::PlayCode is still in its infancy. No fundamental changes are expected, but nevertheless backwards compatibility is not yet guaranteed.

DESCRIPTION

Top

It aims to change the code to be better (to be worse if you want).

More description and API detais will come later.

PLUGINS

Top

Acme::PlayCode::Plugin::Averything

load all plugins we found.

Acme::PlayCode::Plugin::DoubleToSingle

Play code with Single and Double

Acme::PlayCode::Plugin::ExchangeCondition

Play code with exchanging condition

Acme::PlayCode::Plugin::PrintComma

Play code with printing comma

Acme::PlayCode::Plugin::NumberPlus

Play code with plus number

SEE ALSO

Top

Moose, PPI, MooseX::Object::Pluggable

AUTHOR

Top

Fayland Lam, <fayland at gmail.com>

ACKNOWLEDGEMENTS

Top

The Moose Team.

Jens Rehsack, for the description (RT 53680)

COPYRIGHT & LICENSE

Top


Acme-PlayCode documentation Contained in the Acme-PlayCode distribution.

package Acme::PlayCode;

use Moose;
use PPI;
use Path::Class ();

our $VERSION   = '0.12';
our $AUTHORITY = 'cpan:FAYLAND';

with 'MooseX::Object::Pluggable';

has 'tokens' => (
    is  => 'rw',
    isa => 'ArrayRef',
    auto_deref => 1,
    default    => sub { [] },
);
has 'token_flag' => ( is => 'rw', isa => 'Num', default => 0 );

has 'output' => (
    is => 'rw',
    isa => 'ArrayRef',
    default => sub { [] }
);

sub play {
    my ( $self, $code, $opts ) = @_;
    
    my $file;
    if ( $code !~ /\s/ and -e $code ) {
        $file = Path::Class::File->new($code);
        $code = $file->slurp();
    }
    
    # clear to multi-run
    $self->output( [] );
    $self->token_flag( 0 );
    
    my $doc    = PPI::Document->new( \$code );
    $self->tokens( $doc->find('PPI::Token') );

    $self->do_with_tokens();
    
    my @output = @{ $self->output };
    # check Acme::PlayCode::Plugin::PrintComma
    @output = grep { $_ ne 'Acme::PlayCode::!@#$%^&*()_+' } @output;
    my $output = join('', @output);
    if ( $opts->{rewrite_file} and $file ) {
        my $fh = $file->openw();
        print $fh $output;
        $fh->close();
        
    }
    return $output;
}

sub do_with_tokens {
    my ( $self ) = @_;
    
    while ( $self->token_flag < scalar @{$self->tokens}) {
        my $orginal_flag = $self->token_flag;
        my $content = $self->do_with_token_flag( $self->token_flag );
        push @{ $self->output }, $content if ( defined $content );
        # if we don't move token_flag, ++
        if ( $self->token_flag == $orginal_flag ) {
            $self->token_flag( $self->token_flag + 1 );
        }
    }
}

sub do_with_token_flag {
    my ( $self, $token_flag ) = @_;
    
    my @tokens = $self->tokens;
    my $token = $tokens[$token_flag];
    
    return $self->do_with_token( $token );
}

sub do_with_token {
    my ( $self, $token ) = @_;

    my $token_flag = $self->token_flag;
    my @tokens = $self->tokens;
    if ( $token->isa('PPI::Token::HereDoc') ) {
        my @output = @{ $self->output };
        
        my @next_tokens;
        my $old_flag = $token_flag;
        while ( $old_flag++ ) {
            push @next_tokens, $tokens[$old_flag];
            last if ( $tokens[$old_flag]->content eq ';' );
        }
        push @output, $token->content,
            join('', map { $_->content } @next_tokens ), "\n",
            join('', $token->heredoc),
            $token->terminator;
        
        # skip next itself and next ';'
        $self->token_flag( $token_flag + 1 + scalar @next_tokens );
        $self->output( \@output );
        return;
    } else {
        return $token->content;
    }
}

no Moose;
__PACKAGE__->meta->make_immutable;

1;
__END__