| Hailo documentation | Contained in the Hailo distribution. |
Hailo::UI::ReadLine - A UI for Hailo using Term::ReadLine
This module is called internally by Hailo, it takes no options.
A ReadLine interface will be presented when calling hailo on the
command-line with only a --brain argument:
hailo --brain hailo.sqlite
Presents a ReadLine interface using Term::ReadLine, the Term::ReadLine::Gnu frontend will be used.
Ævar Arnfjörð Bjarmason <avar@cpan.org>
Copyright 2010 Ævar Arnfjörð Bjarmason.
This program is free software, you can redistribute it and/or modify it under the same terms as Perl itself.
| Hailo documentation | Contained in the Hailo distribution. |
package Hailo::UI::ReadLine; BEGIN { $Hailo::UI::ReadLine::AUTHORITY = 'cpan:AVAR'; } BEGIN { $Hailo::UI::ReadLine::VERSION = '0.69'; } use 5.010; use Any::Moose; use Any::Moose 'X::StrictConstructor'; use Encode 'decode'; use Hailo; use Term::ReadLine; use Data::Dump 'dump'; use namespace::clean -except => 'meta'; with qw(Hailo::Role::Arguments Hailo::Role::UI); sub BUILD { $ENV{PERL_RL} = 'Perl o=0' unless $ENV{PERL_RL}; return; } sub run { my ($self, $hailo) = @_; my $name = 'Hailo'; my $term = Term::ReadLine->new($name); my $command = qr[ ^ # A dot-prefix like in SQLite \. # We only have Hailo methods matching this (?<method> [a-z_]+ ) # Optional arguments. These'll be passed to eval() before being # passed to the method \s* (?: (?<arguments>.+) )? $]x; print $self->_intro; while (defined (my $line = $term->readline($name . '> '))) { $line = decode('utf8', $line); given ($line) { when (/$command/p) { when ($+{method} eq 'help') { print $self->_help($hailo); } when ($+{method} ~~ [ qw< quit exit >]) { say $hailo->reply("Dave, this conversation can serve no purpose anymore. Goodbye.") // "Bye!"; exit 0; } default { my $meth = $+{method}; my @args = defined $+{arguments} ? eval $+{arguments} : (); local ($@, $!); eval { say dump $hailo->$meth(@args); }; if (my $err = $@) { chomp $err; say STDERR "Failed on <<${^MATCH}>>: <<$err>>"; } } } default { my $answer = $hailo->learn_reply($line); say $answer // "I don't know enough to answer you yet."; } } } print "\n"; return; } sub _intro { my ($self) = @_; my $intro = <<"INTRO"; Welcome to the Hailo interactive shell Enter ".help" to show the built-in commands. Input that's not a command will be passed to Hailo to learn, and it'll reply back. INTRO return $intro; } sub _help { my ($self, $hailo) = @_; my $include = qr/ ^ _go /x; my $exclude = qr/ _ (?: version | order | progress | random_reply | examples | autosave | brain | class ) $/x; my @attr; for my $attr ($hailo->meta->get_all_attributes) { # Only get attributes that are valid command-line options next unless $attr->name ~~ $include; # We don't support changing these in mid-stream next if $attr->name ~~ $exclude; push @attr => { name => do { my $tmp = $attr->cmd_flag; $tmp =~ tr/-/_/; $tmp; }, documentation => $attr->documentation, }; } push @attr => { name => 'quit', documentation => "Exit this chat session", }; my $help = <<"HELP"; These are the commands we know about: HELP my @sorted = sort { $a->{name} cmp $b->{name} } @attr; for my $cmd (@sorted) { $help .= sprintf " %-14s%s\n", '.'.$cmd->{name}, $cmd->{documentation}; } $help .= <<"HELP"; The commands are just method calls on a Hailo object. Any arguments to them will be passed through eval() used as method arguments. E.g.: .train "/tmp/megahal.trn" Trained from 350 lines in 0.54 seconds; 654.04 lines/s () Return values are printed with Data::Dump: .stats (1311, 2997, 3580, 3563) Any input not starting with "." will be passed through Hailo's learn_reply method: Hailo> Help, mommy! Really? I can't. It's an ethical thing. HELP return $help; } __PACKAGE__->meta->make_immutable;