Net-CLI-Interact

 view release on metacpan or  search on metacpan

lib/Net/CLI/Interact/Phrasebook.pm  view on Meta::CPAN

    $self->logger->log('phrasebook', 'debug', 'storing', $data->{type}, $data->{name});

    my $slot = '_'. lc $data->{type};
    $self->$slot->{$data->{name}}
        = Net::CLI::Interact::ActionSet->new({
            actions => $self->_resolve_matches($data->{actions})
        });
}

sub BUILD {
    my $self = shift;
    $self->load_phrasebooks;
}

# parse phrasebook files and load action objects
sub load_phrasebooks {
    my $self = shift;
    my $data = {};
    my $stash = { prompt => [], macro => [] };

    foreach my $file ($self->_find_phrasebooks) {
        $self->logger->log('phrasebook', 'info', 'reading phrasebook', $file);
        my @lines = $file->slurp;
        while ($_ = shift @lines) {
            # Skip comments and empty lines
            next if m/^(?:#|\s*$)/;

            if (m{^(prompt|macro)\s+(\w+)\s*$}) {
                if (scalar keys %$data) {
                    push @{ $stash->{$data->{type}} }, $data;
                }
                $data = {type => $1, name => $2};
                next;
            }
            # skip new sections we don't yet understand
            elsif (m{^\w}) {
                $_ = shift @lines until m{^(?:prompt|macro)};
                unshift @lines, $_;
                next;
            }

            if (m{^\s+send\s+(.+)$}) {
                my $value = $1;
                $value =~ s/^["']//; $value =~ s/["']$//;
                push @{ $data->{actions} }, {
                    type => 'send', value => $value,
                };
                next;
            }

            if (m{^\s+put\s+(.+)$}) {
                my $value = $1;
                $value =~ s/^["']//; $value =~ s/["']$//;
                push @{ $data->{actions} }, {
                    type => 'send', value => $value, no_ors => 1,
                };
                next;
            }

            if (m{^\s+match\s+(.+)\s*$}) {
                my @vals = split m/\s+or\s+/, $1;
                if (scalar @vals) {
                    push @{ $data->{actions} },
                        {type => 'match', value => \@vals};
                    next;
                }
            }

            if (m{^\s+follow\s+/(.+)/\s+with\s+(.+)\s*$}) {
                my ($match, $send) = ($1, $2);
                $send =~ s/^["']//; $send =~ s/["']$//;
                $data->{actions}->[-1]->{continuation} = [
                    {type => 'match', value => [qr/$match/]},
                    ## no critic (ProhibitStringyEval)
                    {type => 'send',  value => eval "qq{$send}", no_ors => 1}
                    ## use critic
                ];
                next;
            }

            die "don't know what to do with this phrasebook line:\n", $_;
        }
        # last entry in the file needs baking
        push @{ $stash->{$data->{type}} }, $data;
        $data = {};
    }

    # bake the prompts before the macros, to allow macros to reference
    # prompts which appear later in the same file.
    foreach my $t (qw/prompt macro/) {
        foreach my $d (@{ $stash->{$t} }) {
            $self->_bake($d);
        }
    }
}

# finds the path of Phrasebooks within the Library leading to Personality
sub _find_phrasebooks {
    my $self = shift;
    my @libs = (ref $self->library ? @{$self->library} : ($self->library));
    my @alib = (ref $self->add_library ? @{$self->add_library} : ($self->add_library));

    # first find the (relative) path for the requested personality
    # then within each of @libs gather the files along that path

    my $target = $self->_find_personality_in( @libs, @alib );
    die (sprintf "error: unknown personality: '%s'\n",
            $self->personality) unless $target;

    my @files = $self->_gather_pb_from( $target, @libs, @alib );
    die (sprintf "error: personality '%s' contains no phrasebook files!\n",
            $self->personality) unless scalar @files;

    return @files;
}

sub _find_personality_in {
    my ($self, @libs) = @_;
    my $target = undef;

    foreach my $lib (@libs) {



( run in 0.624 second using v1.01-cache-2.11-cpan-71847e10f99 )