カレンダ−・プログラムの改良(5)−キーの直接入力

Perl には、簡単に使えるファンクションがたくさんありますが、それでも、あらゆるプログラムに対応できるようにはなっていません。もしそうしたら、膨大な数のファンクションになり、Perl をコンパクトに保つことができなくなるからです。Perl の基本的なファンクション以外のものは、ユーザが後で追加できるように、モジュールの形で用意されています。

カレンダープログラムの仕上げとして、メニューのキーを直接入力するようにしたい(つまり、リターン・キーを押さなくてもよいようにする)のですが、そのファンクションがないので、では、モジュールで対応しようということで、CPAN のウェブページをチェックしました。CPAN というのは Comprehensive Perl Archive Network の略で、Comprehensive というだけあって、Perl に関するものはここに何でもあります。本家のページは www.cpan.org なんですが、モジュールの検索などの場合は search.cpan.org で調べるほうがてっとりばやいと思い、そこをあたってみましたら、Term::ReadKey というモジュールがありました。termreadkey-2.15.tar.gz をダウンロードして、次の手順でモジュールを組み込みました。次のプロンプトの $ はユーザ、# はスーパーユーザをあらわします。スーパーユーザになるには su コマンドでパスワードをいれればいいですね。

$ tar -fvxz termreadkey-2.15.tar.gz
$ cd termreadkey-2.15
$ perl Makefile.PL
$ make
$ make test
$ su
Password:
# make install
# exit
$ cd ..
$ perldoc Term::ReadKey
最後の perldoc Term::ReadKey は、このモジュールのマニュアルを読むためのものです。マニュアルは man 形式で、スペースを押してページを進め、Q で終了です。

そのマニュアルによれば、「ReadMode で、入力モードを指定し、ReadKey でキーボードからの入力を読みとる」とありました。ここでは入力モード 3 を選び、キーボードからの入力を $key 入れ、入力モードに 0 を指定することによって、もとにもどしておくようにしました。これを select() サブルーチンの $input = のかわりにおきました。

ReadMode 3;
$key = ReadKey;
ReadMode 0;
ただし、モジュールを使うには、プログラムの先頭で、use <モジュール名> の宣言をしておかなくてはなりません。
#!/usr/bin/perl
#
# calendar05.pl
#

use Term::ReadKey;

ここまで出来れば、あとは select() サブルーチンで の選択部分で $input を $key にかえればいいだけですが、ひとつだけ問題があります。if($input eq '') という部分を if($key eq '') としても駄目です。$key には「リターン」の価が入っているからです。'b' を押したかどうかは if($key eq 'b')で、「シフト」と'b'を押したかどうかは if($key eq 'B') でチェックできますが、文字を返さない「リターン」キーの場合は、コードで表して

if($key eq chr(10))
としなければなりません。chr(10) は、「文字コード 10 番目の文字」という意味です。ある文字の文字コードが何番目かは ord('A') として得ることができます。'A' は 65 です。ですから、上の式は
if(ord($key) == 10)
と書いても良いことになります

以下は書き換えた select() サブルーチンです。

sub select(){
local ($input, $year, $month);
($year, $month) = @_;
# キーボードからの直接入力 
ReadMode 3;
$key = ReadKey;
ReadMode 0;
print "\n\n";
# 選択と年月の計算
if($key eq 'q'){
    exit(0);
    }
elsif($key eq 'b'){
    $year = $year - ($month == 1);
    $month = $month - ($month > 1) + 11 * ($month == 1);
    }
if($key eq 'B'){
    $year--;
    }
if($key eq 'n'){
    $year = $year + ($month == 12);
    $month = $month + ($month < 12) - 11 * ($month == 12);
    }
if($key eq 'N'){
    $year++;
    }
if($key eq chr(10)){
    $year = $this_year;
    $month = $this_month;
    }
return ($year, $month);
}

[前のぺ−ジ] [目次] [次のぺ−ジ]