Perl の Term::ReadLine で補完

Term::ReadLine::Gnu を入れたうえで、$term->Attribs->{attempted_completion_function} あたりをごにょごにょすればできる???? みたいですけどーーーー わたしの環境だとふり〜ずしちゃうみたいです>< なんでだろう;;

#!/usr/bin/perl

use strict;
use warnings;
use Term::ReadLine;

my $cmds = {
	foo => sub {
		print "foo\n";
	},

	exit => sub {
		exit;
	}
};

my $term = new Term::ReadLine("Simple Complete Test");
my $attribs = $term->Attribs;

$attribs->{completion_append_character} = "";
$attribs->{attempted_completion_function} = sub {
	my ($text, $line, $start, $end) = @_;
	return $term->completion_matches($text, sub {
		my ($text, $state) = @_;
		foreach (keys %$cmds) {
			return $_ if /^$text/;
		}
		return undef;
	});
};

$SIG{INT} = sub {
	$term->modifying;
	$term->delete_text;
	$attribs->{point} = $attribs->{end} = 0;
	$term->redisplay;
};

while (defined($_ = $term->readline("> "))) {
	next if /^\s*$/;
	print $_, "\n";
	eval {
		if ($cmds->{$_}) {
			&{$cmds->{$_}}();
		} else {
			print "Command not found.\n";
		}
	}; if ($@) {
		print $@, "\n";
	}
}

なにか足りないのかなぁあ??

perlsh を読みなおしてした、それとおなじみたいに書いたらうまくいったよ☆ foreach の部分が無限ループしてたみたい

my ($i, @matches);

$attribs->{completion_append_character} = "";
$attribs->{attempted_completion_function} = sub {
	my ($text, $line, $start, $end) = @_;
	return $term->completion_matches($text, sub {
		my ($text, $state) = @_;
		if ($state) {
			$i++;
		} else {
			$i = 0;
			@matches = keys %$cmds;
		}
		for (; $i <= $#matches; $i++) {
			return $matches[$i] if ($matches[$i] =~ /^\Q$text/);
		}
		return undef;
	});
};

completion_matches に渡すサブルーチンは「ヒットしたらその文字列、ヒットしなかったら undef」と返せばいいのかな??? 一回の補完プロセスで何度も呼びだしがあるみたい><