簡単 Q&A 作成プログラム note.rb

参考書を読んでいるときに、簡単に Q&A を作成するプログラムがあったら良いのにと思ったことはないでしょうか。筆者もそう思って Perl や Ruby を使って色々と作ってみましたが、コンテンツの作成が意外に面倒で実用には至っていませんでした。

此の度、るびまの YAML の解説を見つけて利用してみたところ、ほぼ、使えるようになったと思ったので紹介します。このホームページの、YAML で遊ぼうで紹介したものとほぼ同じですが、コンテンツのキー入力をできるだけ減らすように変更してあります。note.rb のソースは次のようになります。

#!/usr/bin/ruby
# note.rb: interactive card program
# written by tnomura in /05/07/2006

require 'yaml'

class Card
  def initialize(obj)
    @title = obj["title"]
    @doc = obj["doc"]
    @choice = obj["choice"]
    @link = obj["link"]
  end

  attr_reader :title

  def disp
    puts
    puts "[#{@title}]", @doc
    return nil unless @choice
    puts
    itemNo = 1
    @choice.each {|item| print "#{itemNo}: #{item}\t"; itemNo += 1}
    puts
    print "chose number > "
    i = gets.to_i - 1
    @link[i]
  end
end

card_table = {}

objects = YAML.load_stream(File.read(ARGV.shift)).documents
first_title = objects[0]["title"]

objects.each do |obj|
  card = Card.new(obj)
  card_table[card.title] = card
end

card = card_table[first_title]

while true
  next_card = card.disp
  card = card_table[next_card]
  break if not card
end

note.rb 用のデータ data.yaml は次のようになります。

# data.yaml : YAML data file for note.rb
# written by tnomura on /05/07/2006

--- 
title: card 1
doc: |
  This is an interactive card program.
  Press 1 when you go to card 2.
  Press 2 when you exit this program.
choice: [to card 2, to the last, end]
link:  [card 2, the last, ~]

---
title: card 2
doc: |
  This is another card.
  Press 1 when you go to card 1.
  Press 2 when you exit this program.
choice: [to card 1, to the last, end]
link:  [card 1, the last, ~]

--- 
title: the last
doc: |
  This is the last card.
choice: ~

データの表記法は YAML に従っているので説明は省きます。一画面の最初にはオブジェクトのはじまりを表す --- を引きます。title: フィールドには、その画面のタイトルの名前を書きます。doc: フィールドが本文ですが、複数行を表示するために | を表示し、次の行から本文を記述します。YAMLの文法で、本文の先頭はスペースでインデントしないとエラーになります。choice: フィールドには選択肢の表示を配列で与えます。link: フィールドには、choice: の選択肢に合う画面のタイトルを配列で与えます。次にどの画面にも移動せず、そこでプログラムを終了する場合には ~ (チルダ)を記入しておきます。

基本的な画面は、タイトルと、選択肢と、番号入力のカーソルが表示されますが、最後のカードのように選択肢が必要ない場合もあります。その場合には choice: フィールドに単に ~ (チルダ)のみを入力しておきます。

このプログラムの実行結果を次に示します。

$ ruby note.rb data.yaml

[card 1]
This is an interactive card program.
Press 1 when you go to card 2.
Press 2 when you exit this program.

1: to card 2    2: to the last  3: end
chose number > 1

[card 2]
This is another card.
Press 1 when you go to card 1.
Press 2 when you exit this program.

1: to card 1    2: to the last  3: end
chose number > 2

[the last]
This is the last card.

サンプルプログラムとデータを note.tar.gz に置いておきます。データファイルには、日本語も使えます。