自分で作ってみた感じだとなかなかよさげな気がする。csvにもとのデータを保存しているので、他の用途に使うのも楽チン。紙の単語帳だとできないところ。TOEFL対策講座の勉強に使ってます。
特徴
- registerって打つとcsvファイルに登録
- 間違ったらdeleteで消せる
- questionって打つと問題を出すような形になって止まる
- cとq以外の任意のキーを押すと答えが出る
- cを打つと覚えたということで、次回からは出てこない
- qを打つと問題を出すモードから脱出
自分的には問題を出したときにワンストロークでいけるのがいいかなっと思ったところ。
#!/usr/bin/perl package My::Tango; use strict; use warnings; use Term::ReadLine; use Data::Dumper; use Text::CSV::Simple; use Term::ReadKey; use Jcode; use Smart::Comments; my %cmds; $cmds{help} = sub { print join( ' ', sort keys %cmds ), "\n"; }; $cmds{hello_world} = sub { print "hello world!!\n"; }; $cmds{ls} = sub { my $self = shift; foreach my $key ( keys %{ $self->{dict} } ) { printf "%-10s : %s \n", $key, Jcode::convert( $self->{dict}->{$key}, 'euc-jp' ); } }; $cmds{register} = sub { my $self = shift; my $term = $self->{term}; my $prompt = "登録したい単語を入力してください: "; my $tango = $term->readline($prompt); $prompt = "その意味を登録してください: "; my $imi = $term->readline($prompt); ${$self}{dict}{$tango} = $imi; print "登録が完了しました\n"; }; $cmds{delete} = sub { my $self = shift; my $term = $self->{term}; my $prompt = "削除したい語を入力してください: "; my $tango = $term->readline($prompt); delete ${$self}{dict}{$tango}; print "削除しました\n"; }; $cmds{exit} = sub { my $self = shift; print "Good Bye!!\n"; $self->save(); $self->save_done(); exit; }; $cmds{question} = sub { my $self = shift; my $term = $self->{term}; my $prompt = $self->{prompt}; ReadMode 'cbreak'; foreach my $key ( keys %{ $self->{dict} } ) { printf "%-10s : ", $key; my $input = ReadKey(0); printf "%s \n", Jcode::convert( $self->{dict}->{$key}, 'euc-jp' ); if ( $input eq "q" ) { last; }elsif($input eq "c"){ $self->complete($key); } } ReadMode 'normal'; }; sub new { my ($class) = @_; my $term = Term::ReadLine->new('my tango'); my $prompt = "tango> "; bless { dict => undef, complete => undef, term => $term, prompt => $prompt, }, $class; } sub prepare { my $self = shift; my $csv = Text::CSV::Simple->new( { binary => 1, #日本語を通すため } ); $csv->field_map(qw/tango imi/); my @array = $csv->read_file(".tango"); foreach my $dict (@array) { $self->{dict}->{ $dict->{tango} } = $dict->{imi}; } } sub start { my $self = shift; my $term = $self->{term}; my $prompt = $self->{prompt}; my $OUT = $term->OUT || \*STDOUT; while ( defined( $_ = $term->readline($prompt) ) ) { if ( exists $cmds{$_} ) { # 入力に対応するコマンドがあれば、 &{ $cmds{$_} }($self); # それを実行する } else { print "そのコマンドは存在しません\n"; } $term->addhistory($_) if /\S/; } } sub complete { my $self = shift; my $tango = shift; $self->{complete}->{$tango} = $self->{dict}->{$tango}; delete ${$self}{dict}{$tango}; } sub save { my $self = shift; open FILE, "> .tango" or die "$!"; my $content = ""; my $tango; my $imi; my @list; foreach my $key ( keys %{ $self->{dict} } ) { $tango = $key; $imi = Jcode::convert( $self->{dict}->{$key}, 'euc-jp' ); @list = ( $tango, $imi ); $content = $content . "\"" . join( "\",\"", @list ) . "\"\n"; } print FILE $content; close FILE; } sub save_done { my $self = shift; open FILE, "> .done_tango" or die "$!"; my $content = ""; my $tango; my $imi; my @list; foreach my $key ( keys %{ $self->{complete} } ) { $tango = $key; $imi = Jcode::convert( $self->{complete}->{$key}, 'euc-jp' ); @list = ( $tango, $imi ); $content = $content . "\"" . join( "\",\"", @list ) . "\"\n"; } print FILE $content; close FILE; } package main; use strict; use warnings; use Data::Dumper; my $tango = My::Tango->new(); $tango->prepare(); $tango->start();
関数のリファレンスとかが出てきたので結構いみふになったが、結構いい勉強になった感じではある。