Filter::Eratosthenes

LLRing の締め切りは過ぎちゃったけど。Filter::Eratosthenes.
entry.body に含まれる素数以外の数値を削除 (又は config で指定された文字列に置換) するフィルタ。誰かネタにしてたような……

package Plagger::Plugin::Filter::Eratosthenes;
use strict;
use base qw( Plagger::Plugin::Filter::Base );
use List::MoreUtils qw(all before_incl);

sub register {
    my ($self, $context) = @_;
    $context->register_hook(
        $self,
        'plugin.init' => \&init_primes,
    );
    $self->SUPER::register($context);
}

sub init_primes {
    my($self, $context) = @_;

    $self->conf->{replace} ||= '';
    $self->conf->{max}     ||= 100;
    $self->log( info => 'initializing primes for 2..'. $self->conf->{max} );

    my @primes = (2);
    for my $n (3..$self->conf->{max}){
        push @primes, $n
            if all{$n % $_ } before_incl{ sqrt $n <= $_ } @primes;
    }
    $self->{primes}   = \@primes;
    $self->{is_prime} = { map { $_ => 1 } @primes };

    $self->log( info => 'initializing primes done.' );
    1;
}

sub filter {
    my($self, $body) = @_;
    my $count;
    $count = ($body =~ s/(\d+)/($1 <= $self->conf->{max} && !$self->{is_prime}->{$1} ? $self->conf->{replace} : $1)/xmseg);
    ($count, $body);
}

1;
plugins:
  - module: CustomFeed::Debug
    config:
      title: 'Test Feed'
      link: 'http://example.com/'
      entry:
        - title: 'Test Entry'
          link: 'http://example.com/1'
          body: '1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100'

  - module: Filter::Eratosthenes
    config:
      max: 10000
      replace: 

これで body は "2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97" になる。