--- /dev/null
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use IO::All;
+
+sub with_file (&) {
+ my ($code) = @_;
+ my $fname = $_;
+ my $data < io($fname);
+ {
+ local $_ = $data;
+ $code->();
+ $data = $_;
+ }
+ $data > io($fname);
+}
+
+sub with_class_block (&) {
+ my ($code) = @_;
+ $_ =~ s{^class\s*(.*?)which\s*{(.*?)^};}
+ {
+ local *_ = { header => $1, body => $2 };
+ $code->();
+ }sme;
+}
+
+sub parse_header {
+ my $h = $_{header};
+ $h =~ s/^\s*\S+\s+// || die;
+ my @base;
+ while ($h =~ /is\s*(\S+?),?/g) {
+ push(@base, $1);
+ }
+ return @base;
+}
+
+sub build_extends {
+ my $base = join(', ', parse_header);
+ ($base ? "extends ${base};\n\n" : '');
+}
+
+sub sq { # short for 'strip quotes'
+ my $copy = $_[0];
+ $copy =~ s/^'(.*)'$/$1/;
+ $copy =~ s/^"(.*)"$/$1/;
+ $copy;
+}
+
+sub filtered_body {
+ local $_ = $_{body};
+ s/^ //g;
+ s/implements *(\S+).*?{/"sub ${\sq $1} {"/ge;
+ s/^does/with/g;
+ $_;
+}
+
+sub top { "use namespace::clean -except => [ qw(meta) ];\n" }
+sub tail { "__PACKAGE__->meta->make_immutable;\n"; }
+
+for ("lib/Reaction/InterfaceModel/Object.pm", "lib/Reaction/InterfaceModel/Action/DBIC/Result.pm") {
+ with_file {
+ with_class_block {
+ return top.build_extends.filtered_body.tail;
+ };
+ };
+}
+
+1;