Great toy. Kudos ;-)
Here's a more usable interact using Term::Readline.
OFC, I named it interact2 just to avoid overriding your code ;-)
sub interact2 {
my $self = shift;
eval { require Term::ReadLine };
die "This method requires Term::ReadLine.\nError was: $@\n" if $@;
# used for completion
my @commands = map { $_->[0] } values %{$palias};
my $term = Term::ReadLine->new('Logo');
$term->Attribs->{attempted_completion_function} = sub {
my $word = shift;
$term->Attribs->{completion_word} = \@commands;
return $term->completion_matches( $word,
$term->Attribs->{list_completion_function} );
};
$term->Attribs->{attempted_completion_over} = sub {};
while () {
my $cmd = $term->readline( 'logo> ' );
last if !defined $cmd;
for ($cmd) {
s/^\s+//;
s/\s+$//;
}
next if $cmd !~ /\S/;
if ( $cmd eq '?' || $cmd eq 'help' ) {
$self->interactive_help();
}
elsif ( $cmd =~ /^(?i:q(?:uit)?|bye|exit)$/ ) {
last;
}
else {
$self->interactive_command($cmd);
# adding only valid commands would be nice
# - possible if "interactive_command" returns some status
$term->addhistory($cmd);
}
}
return 0; # Exit interactive mode
}
Obviously, it requires Term::ReadLine to basically work, and Term::ReadLine::Gnu
to be able to use the custom completion method.