1 package Devel::REPL::Plugin::Turtles;
2 use Devel::REPL::Plugin;
4 use Scalar::Util qw(reftype);
6 use namespace::clean -except => [ 'meta' ];
8 has default_command_prefix => (
11 default => sub { qr/\#/ },
14 has turtles_matchers => (
15 traits => ["Collection::Array"],
16 isa => "ArrayRef[RegexpRef|CodeRef]",
19 default => sub { my $prefix = shift->default_command_prefix; [qr/^ $prefix (\w+) \s* (.*) /x] },
21 unshift => "add_turtles_matcher",
25 around 'formatted_eval' => sub {
27 my ($self, $line, @args) = @_;
29 if ( my ( $command, @rest ) = $self->match_turtles($line) ) {
30 my $method = "command_$command";
31 my $expr_method = "expr_$method";
33 if ( my $expr_code = $self->can($expr_method) ) {
34 if ( my $read_more = $self->can("continue_reading_if_necessary") ) {
35 push @rest, $self->$read_more(pop @rest);
37 $self->$expr_code($next, @rest);
38 } elsif ( my $cmd_code = $self->can($method) ) {
39 return $self->$cmd_code($next, @rest);
41 unless ( $line =~ /^\s*#/ ) { # special case for comments
42 return $self->format($self->error_return("REPL Error", "Command '$command' does not exist"));
46 return $self->$next($line, @args);
51 my ( $self, $line ) = @_;
53 foreach my $thingy ( @{ $self->turtles_matchers } ) {
54 if ( reftype $thingy eq 'CODE' ) {
55 if ( my @res = $self->$thingy($line) ) {
59 if ( my @res = ( $line =~ $thingy ) ) {
74 Devel::REPL::Plugin::Turtles - Generic command creation using a read hook