Tbpgr Blog

Ruby プログラマ tbpgr(てぃーびー) のブログ

CUI ツールにも人間への配慮を。人間にとって読みやすい出力フォーマットのオプションを用意する

概要

CUI ツール手軽さ、自動化との相性 などのコンテキストで語られる事が多いですが、
人間が利用する際の可読性が必要となるケースもあります。

今回は、 レコードと列からなる大量のデータを扱う場合 を想定し、
表形式のフォーマット出力について扱います。
RDBCUI ツールなどでみかけるフォーマットです。

元ネタ

CUI における人間からみた可読性については、
書籍「 Build Awesome Command-Line Applications in Ruby2 」 を参考にしています。

サンプル

サンプル仕様

  • gems gem を利用して gem の情報を取得
  • gem 名, ダウンロード数, 現バージョンのダウンロード数, 言語, 作者を出力する

Before

CSVフォーマットで出力した場合。
自動処理に向いているが、人間が見るには見にくいフォーマット。

サンプルコード

require 'gems'

def load_gem_info(gem_name)
  gem_info = Gems.info(gem_name)
  [
    gem_info['name'],
    gem_info['downloads'],
    gem_info['version_downloads'],
    gem_info['platform'],
    gem_info['authors']
  ]
end

header = %w(gem_name downloads version_downloads platform authors)
kosi = load_gem_info('kosi')
terminal_table = load_gem_info('terminal-table')
puts [header, kosi, terminal_table].map { |e|e.join(',') }.join("\n")

出力

% ruby sample1.rb
gem_name,downloads,version_downloads,platform,authors
kosi,1104,307,ruby,tbpgr
terminal-table,2220841,2139508,ruby,TJ Holowaychuk, Scott J. Goldman

After

テーブルフォーマットで出力した場合。
自動処理には不向きだが、人間には見やすいフォーマット。

サンプルコード

require 'terminal-table'
require 'gems'

def load_gem_info(gem_name)
  gem_info = Gems.info(gem_name)
  [
    gem_info['name'],
    gem_info['downloads'],
    gem_info['version_downloads'],
    gem_info['platform'],
    gem_info['authors']
  ]
end

header = %w(gem_name downloads version_downloads platform authors)
kosi = load_gem_info('kosi')
terminal_table = load_gem_info('terminal-table')
table = Terminal::Table.new :headings => header, :rows => [kosi, terminal_table]
puts table

出力

f:id:tbpg:20150414025948p:plain

日本語を含む出力の場合

terminal-table 利用時

terminal-table で日本語を含む文字列を表形式で出力した場合,
フォーマットがずれてしまいます。

require 'terminal-table'
require 'gems'

header = %w(列1 列2)
rows = [%w(ほげ ひげひげ), %w(ほげほげほげ ひげ)]
table = Terminal::Table.new :headings => header, :rows => rows
puts table

f:id:tbpg:20150414025214p:plain

kosi 利用時

kosi は自作の gem で、日本語の場合でも表形式の出力が乱れません。

require 'kosi'
require 'gems'

header = %w(列1 列2)
rows = [header, %w(ほげ ひげひげ), %w(ほげほげほげ ひげ)]
kosi = Kosi::Table.new
puts kosi.render(rows)

f:id:tbpg:20150414025219p:plain

参考

テーブルフォーマットで標準出力を行っている CLI ツールですが、
GitHubterminal_table を検索してみると、 8,011 件 も存在します。

f:id:tbpg:20150414025228p:plain

外部資料

書籍