Acme-Shotgun

 view release on metacpan or  search on metacpan

Readme.md  view on Meta::CPAN

Acme::Shotgun - Shoots holes in files

# SYNOPSIS

    use Acme::Shotgun;

    my $gun = Acme::Shotgun->new(
        type  => 'double',   # double | pump
        load  => 'bird',     # bird | buck | slug
        quiet => 0,
        debug => 0,
    );

    $gun->reload();
    $gun->check();
    $gun->fire(target => '/path/to/file.txt');

# DESCRIPTION

Acme::Shotgun is an object-oriented Perl module that shoots holes in plain
text files. Supports double-barrel and pump-action shotgun types, with

Readme.md  view on Meta::CPAN

## new(%args)

Constructs and returns a new Acme::Shotgun object. The gun is automatically
reloaded on construction.

    my $gun = Acme::Shotgun->new(
        type    => 'double',  # 'double' (default) or 'pump'
        load    => 'bird',    # 'bird' (default), 'buck', or 'slug'
        shots   => undef,     # optional: cap the number of rounds loaded
        quiet   => 0,         # suppress all output
        debug   => 0,         # dry-run mode, no file modifications
        verbose => 1,         # verbose output (disabled automatically if quiet)
    );

Dies with an error if an invalid `type` or `load` value is given.

## reload()

Loads the magazine for the current shotgun type and ammunition. Default
capacity is 2 rounds for `double` and 5 rounds for `pump`. If `shots`
was set in the constructor and is less than the default capacity, it is

Readme.md  view on Meta::CPAN


Prints the current magazine state - shotgun type, ammunition type, and
remaining round count. Returns the object for chaining.

## fire(target => $path)

Fires all remaining rounds at the given target file, shooting holes into
it with each shot. The file must be an existing plain text file under 1 GB.
Each shot prints `POW!` unless `quiet` is set.

In `debug` mode, `POW!` is still printed but no file modifications are
made. Returns the object for chaining.

# REFERENCE

## Shotgun Types

- **double**

    Double-barrel. Holds 2 rounds by default. This is the default type.

lib/Acme/Shotgun.pm  view on Meta::CPAN

our $VERSION = '0.03';

sub new {
    my ($class, %args) = @_;

    my $self = {
        type       => 'double',
        load       => 'bird',
        shots      => undef,
        quiet      => 0,
        debug      => 0,
        verbose    => 1,
        num_rounds => 0,
        %args,
    };

    die "Invalid shotgun type '$self->{type}'! Must be 'double' or 'pump'.\n"
        unless $self->{type} =~ /^(?:double|pump)$/;

    die "Invalid ammo type '$self->{load}'! Must be 'bird', 'buck', or 'slug'.\n"
        unless $self->{load} =~ /^(?:bird|buck|slug)$/;

    $self->{verbose}++ if $self->{debug};
    $self->{verbose} = 0 if $self->{quiet};

    bless $self, $class;
    $self->reload();

    return $self;
}

sub reload {
    my $self = shift;

lib/Acme/Shotgun.pm  view on Meta::CPAN

    }

    return $self;
}

## Private methods

sub _shoot {
    my ($self, $target) = @_;

    if ($self->{debug}) {
        print "POW! (debug - no file modified)\n";
        return;
    }

    open my $in, '<', $target or die "Unable to open target file: $target\n";
    my @lines = <$in>;
    close $in;

    my $height   = scalar @lines;
    my $width    = 80;
    my $v_buffer = int rand($height);

lib/Acme/Shotgun.pm  view on Meta::CPAN

Acme::Shotgun - Shoots holes in files

=head1 SYNOPSIS

    use Acme::Shotgun;

    my $gun = Acme::Shotgun->new(
        type  => 'double',   # double | pump
        load  => 'bird',     # bird | buck | slug
        quiet => 0,
        debug => 0,
    );

    $gun->reload();
    $gun->check();
    $gun->fire(target => '/path/to/file.txt');

=head1 DESCRIPTION

Acme::Shotgun is an object-oriented Perl module that shoots holes in plain
text files. Supports double-barrel and pump-action shotgun types, with

lib/Acme/Shotgun.pm  view on Meta::CPAN

=head2 new(%args)

Constructs and returns a new Acme::Shotgun object. The gun is automatically
reloaded on construction.

    my $gun = Acme::Shotgun->new(
        type    => 'double',  # 'double' (default) or 'pump'
        load    => 'bird',    # 'bird' (default), 'buck', or 'slug'
        shots   => undef,     # optional: cap the number of rounds loaded
        quiet   => 0,         # suppress all output
        debug   => 0,         # dry-run mode, no file modifications
        verbose => 1,         # verbose output (disabled automatically if quiet)
    );

Dies with an error if an invalid C<type> or C<load> value is given.

=head2 reload()

Loads the magazine for the current shotgun type and ammunition. Default
capacity is 2 rounds for C<double> and 5 rounds for C<pump>. If C<shots>
was set in the constructor and is less than the default capacity, it is

lib/Acme/Shotgun.pm  view on Meta::CPAN


Prints the current magazine state - shotgun type, ammunition type, and
remaining round count. Returns the object for chaining.

=head2 fire(target => $path)

Fires all remaining rounds at the given target file, shooting holes into
it with each shot. The file must be an existing plain text file under 1 GB.
Each shot prints C<POW!> unless C<quiet> is set.

In C<debug> mode, C<POW!> is still printed but no file modifications are
made. Returns the object for chaining.

=head1 REFERENCE

=head2 Shotgun Types

=over 4

=item B<double>

shotgun.pl  view on Meta::CPAN

      Options (required):
          -target                   File you want to shoot holes in

      Options (optional):
          -help                     Print this help menu
          -type [double|pump]       Shotgun type
          -load [bird|buck|slug]    Type of ammunition
          -shots [int]              Number of shots to fire
          -check                    Print mag state before firing
          -quiet                    Suppress output
          -debug                    Debug mode, takes no action
          -verbose                  Verbose mode, more verbose output

      Defaults:
          -type double
          -load bird

    EOF
    exit;
}

my %O = (
    debug   => 0,
    verbose => 1,
    type    => 'double',
    load    => 'bird',
);

GetOptions(\%O,
    'help',
    'debug',
    'verbose!',
    'target=s',
    'type=s',
    'load=s',
    'shots=i',
    'check',
    'quiet',
) or usage();

usage()                             if $O{help};
usage("Missing required argument!") unless $O{target};

my $gun = Acme::Shotgun->new(
    type    => $O{type},
    load    => $O{load},
    shots   => $O{shots},
    quiet   => $O{quiet}   // 0,
    debug   => $O{debug}   // 0,
    verbose => $O{verbose} // 1,
);

$gun->check() if $O{check};
$gun->fire(target => $O{target});

t/01_blastin.t  view on Meta::CPAN

        $gun->fire(target => $target);
    }

    open $fh, '<', $target or die "Can't open: $!";
    my $after = do { local $/; <$fh> };
    close $fh;

    isnt($before, $after, 'file contents changed after firing');
};

subtest 'debug mode does not modify file' => sub {
    my $gun    = quiet_gun(debug => 1);
    my $target = make_target();

    open my $fh, '<', $target or die "Can't open: $!";
    my $before = do { local $/; <$fh> };
    close $fh;

    $gun->fire(target => $target);

    open $fh, '<', $target or die "Can't open: $!";
    my $after = do { local $/; <$fh> };
    close $fh;

    is($before, $after, 'file contents unchanged in debug mode');
};

subtest 'all ammo types fire without error' => sub {
    for my $load (qw(bird buck slug)) {
        my $gun    = quiet_gun(load => $load);
        my $target = make_target();
        lives_ok { $gun->fire(target => $target) } "$load fires without error";
    }
};



( run in 1.120 second using v1.01-cache-2.11-cpan-e1769b4cff6 )