Kentaro Kuribayashi's blog

Software Engineering, Management, Books, and Daily Journal.

eijiro.pl 改をさらに微改造してみた

2006-09-30 追記。
下記パッチを取り込んでいただいたので、このエントリで述べられている内容は、現在、eijiro.pl 改本体に反映されています(コメント欄参照)。

英和/和英辞書は英辞郎を、PDIC との組み合わせでずっと使っていたのですが、コマンドラインからさくっとひきたいなぁと思うことが多くなってきたので、「naoyaのはてなダイアリー - eijiro.pl 改」で公開されている eijiro.pl 改を使い始めました。これでどこからでも一発で辞書を引けます。便利!
ところで、ちと自分的に不便なところがふたつばかりありました。

  1. 訳語の検索結果がページャにわたされるのはいいけど、上限をもうけた上で標準出力に吐いてほしい場合もある
  2. うちのマシンはロケールが UTF8 なので、和英がちゃんと引けない

というわけで、下記に示す改造を施して、

$ perl bin/eijiro.pl -n [--lines] lines word

というふうに head コマンドっぽく、-n または --lines で数値を指定すると、その数の分だけの検索結果を標準出力に吐くようにしてみた。
また同様に、

$ perl bin/eijiro.pl -n [--lines] lines

として、検索語を指定せずに対話モードに入った場合でも、最初に指定した数の分だけをページャではなく、その場で出力します。
また、2 番目のエンコーディングの問題については、Term::Encoding を用いててけとーに対処しました。これでいいのかはわかんないけど、少なくともロケールが UTF8 なうちの環境では問題なく動いていてるのでよしとしましょう。
肝心の辞書データについては、英辞郎のサイトからダウンロードするか、あるいは CD-ROM 版を買うのもいいかもしれません。というか、僕は CD-ROM 版を持っています。

英辞郎 第二版「Special Valueパック」
  • アルク
  • 2005-03-04
  • ¥ 2,850
  • Software

[これはひどい] な改造チックだけど、一応以下に diff を貼っつけておきます。

=== lib/Eijiro/Command/Printable.pm
==================================================================
--- lib/Eijiro/Command/Printable.pm	(revision 1496)
+++ lib/Eijiro/Command/Printable.pm	(local)
@@ -2,14 +2,32 @@
 use strict;
 use warnings;
 use IO::File;
+use Encode qw(from_to);
+use Term::Encoding qw(term_encoding);
 
-my $pager = $ENV{PAGER} || 'less';
+my $pager         = $ENV{PAGER} || 'less';
+my $db_encoding   = 'euc-jp';
+my $term_encoding = Term::Encoding::term_encoding;
 
 sub print {
     my ($class, $eijiro, $line) = @_;
     $line or return;
-    my $p = new IO::File "| $pager";
-    $p->printf("%s\n\t%s\n\n", $_->term, $_->description) for $eijiro->translate($line);
+    from_to($line, $term_encoding, $db_encoding);
+
+    my @translated;
+    if ($eijiro->lines) {
+        @translated = ($eijiro->translate($line))[0..($eijiro->lines - 1)];
+    }
+    else {
+        @translated = $eijiro->translate($line);
+    }
+
+    my $p = new IO::File ' | ' . ($eijiro->lines ? 'cat' : $pager);
+    for my $item (@translated) {
+        from_to(my $term = $item->term,        $db_encoding, $term_encoding);
+        from_to(my $desc = $item->description, $db_encoding, $term_encoding);
+        $p->printf("%s\n\t%s\n\n", $term, $desc);
+    }
     $p->close;
 }
 
=== lib/Eijiro/Command.pm
==================================================================
--- lib/Eijiro/Command.pm	(revision 1496)
+++ lib/Eijiro/Command.pm	(local)
@@ -5,9 +5,14 @@
 use Getopt::Long;
 
 sub factory {
-    my $class = shift;
-    GetOptions(init => \my $init);
-    my $command = join '::', __PACKAGE__, $init ? 'Init' : @ARGV ? 'Argv' : 'Terminal';;
+    my ($class, $eijiro) = @_;
+    GetOptions(
+        init        => \my $init,
+        'lines|n=i' => \my $lines,
+    );
+    $eijiro->lines($lines) if $lines;
+
+    my $command = join '::', __PACKAGE__, $init ? 'Init' : @ARGV ? 'Argv' : 'Terminal';
     $command->require;
     die $@ if $@;
     return $command;
=== lib/Eijiro.pm
==================================================================
--- lib/Eijiro.pm	(revision 1496)
+++ lib/Eijiro.pm	(local)
@@ -12,7 +12,7 @@
 use Eijiro::Driver;
 use Eijiro::Command;
 
-__PACKAGE__->mk_accessors(qw/schema history/);
+__PACKAGE__->mk_accessors(qw/schema history lines/);
 
 sub new {
     my $class = shift;
@@ -53,7 +53,8 @@
 }
 
 sub run_as_command {
-    Eijiro::Command->factory->do(shift);
+    my $self = shift;
+    Eijiro::Command->factory($self)->do($self);
 }
 
 1;