対象読者
- Rubyの入門書を一読した方
- 練習用にRubyのプログラムを作りたいが良い課題が見つからない方
必要なもの
Ruby本体とお好きなエディタを用意してください。RubyGemsも少し使います。
筆者は以下の環境で執筆しています。
ruby 1.8.6-p111 / SAKURAエディタ / WindowsXP SP2 / gem 0.9.5
この連載の目標
作っていく例題としてどんなものがいいかとかなり考えました。今回はRailsを使わないと決めたのでWEBアプリは避けたいし、入門書によくあるようなコマンドライン上で文字がちょっと出るだけというのも面白くないし、GUIアプリも敷居が高そうです。考えた結果、コンソールをいろいろ制御するようなプログラムを作ることにしました。古い人には懐かしく若い人には新鮮かもしれません。見た目は地味ですがなかなか面白いですよ。では始めていきましょう。
コンソールライブラリを使ってみる
Rubyでコンソールアプリを作るには、コンソールライブラリが必要です。
Ruby用のものはいくつかありますが、標準でもCursesというライブラリが入っています。今回はこれを使います。
次の手順に従って拡張ライブラリをインストールしてください。
- "http://jarp.does.notwork.org/win32/"から「pdcurses-2.60-1-mswin32.zip」および「zlib-1.1.4-1-mswin32.zip」をダウンロードし解凍する。
- 解凍された各フォルダの「bin」フォルダにpdcurses.dll、zlib.dllがあるので、それをrubyのインストール先の「bin」フォルダにコピーする。
基本的な扱い方
まずは月並みですが「HelloWorld」的なプログラムです。
エディタを使って次のプログラムを作成してください。
require "curses" Curses::init_screen Curses::setpos(5, 2) Curses::addstr("Cursesの世界にようこそ") Curses::refresh Curses::getch Curses::close_screen
出来上がったらwelcome.rbという名前で保存してください。
実行はコマンドプロンプトで動かすようにしてください。
c:\> ruby welcome.rb
このプログラムを元にCursesの基本的な扱い方を説明していきます。
1行目:まず"curses"をrequire
します。ちなみにCursesライブラリはモジュールなのでオブジェクト生成無しでメソッドを使うことができます。
3行目:最初に必ずinit_screen
を呼ぶ必要があります。このメソッドは画面を初期化します。初期化しないとCursesの他のメソッドを呼び出すことはできません。
反対にプログラムの最後は必ずclose_screen
を呼び出す必要があります。つまりアプリ独自の処理はinit_screen
とclose_screen
の間に書くことになります。
4行目:カーソルをsetpos
メソッドを使って移動します。座標は左上を0,0としてy軸、x軸の順番で指定します。そしてその位置にaddstr
を使って文字列を挿入しています。
5行目:ここまでの処理を実際のコンソールに反映するためにはrefresh
メソッドを呼ぶます。画面のどこかを書き換えたら必ずrefresh
しないといけません。
6行目:getch
とはユーザーの文字入力を受け付けるメソッドです。文字が入るまでずっと待つ動きをします。これがないとこのプログラムが一瞬で終わってしまいますので入れてあります。
ウィンドウを扱う
Cursesはコンソール上に仮想的なウィンドウ(Curses::Windowオブジェクト)を作ることができます。ウィンドウは境界線を文字を使って描いたり、カーソル位置を各々で保持することができます。
初期状態ではコンソール画面全体を覆うウィンドウがひとつ作成されています。次のメソッドによりその既成のウィンドウのCurses::Windowオブジェクトを取得することができます。
Curses::stdscr
ウィンドウ内にサブウィンドウを作ることもできます。Curses::Windowクラスの次のメソッドを使います。
subwin(height, width, y, x)
以下はサブウィンドウを表示するサンプルプログラムです。
最初の例と同じようにエディタで入力しコマンドプロンプトで動かしてみてください。
require "curses" include Curses init_screen begin win = stdscr.subwin(5,30,2,2) win.box(?|,?-,?*) win.setpos(2,2) win.addstr("サブウィンドウです") win.refresh getch ensure close_screen end
前回と異なる部分のみを説明していきます。
まずCursesをinclude
メソッドでMix-inしています。これによりCursesのメソッドが自分のメソッドであるかのように使え、メソッドを呼ぶ度にCurses::
と書くのを省略できます。
続いてinit_screen
の二行下、前述のstdscr
メソッドで既成のウィンドウオブジェクトを取得し、そのサブウィンドウを生成しています。
box
メソッドはウィンドウの境界線を描きます。引数として境界を描く文字の文字コードを渡します。("文字列"ではないことに注意してください。Rubyでは文字コードはその文字に?を付けると得られます。例えば?*はアスタリスク(*)の文字コードになります。)