その他
    ホーム 技術発信 DoRuby [Ruby] コンソールアプリで表を出力しよう

    [Ruby] コンソールアプリで表を出力しよう

    この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    コンソールアプリで表を出力しよう

     この記事について

    メンテナンスや日々の確認のために

    ちょっとしたスクリプトを書くことがあります。

    データなどを確認したい場面では

    タブ区切りでのテキストを出力していましたが

    データ量が大きくなると視認性が悪くなります。

    そこでコンソール上でも表を出力したい!

    となります。

    ※記事内でソースコードを変更する箇所がありますが、利用する場合は自己責任でお願いします。

     formatador

    rubygemsでインストールができる

    formatador

    を使うこととします。

    簡単な使い方は以下の通りです。

    #-*- coding: utf-8 -*-
    require "rubygems"
    require "formatador"
    
    data = [
      {:name => "taro", :age => 30},
      {:name => "hanako", :age => 25}
    ]
    
    Formatador.display_compact_table(data, [:name, :age])
    #第2引数で列順を指定
    
      +--------+-----+
      | name   | age |
      +--------+-----+
      | taro   | 30  |
      | hanako | 25  |
      +--------+-----+
    

    実行すると上記のように表が出力されます。

     日本語表示でずれる

    スクリプト上のdataを以下のように変更して出力してみます。

    data = [
      {:name => "太郎", :age => 30},
      {:name => "花子", :age => 25}
    ]
    
      +------+-----+
      | name | age |
      +------+-----+
      | 太郎   | 30  |
      | 花子   | 25  |
      +------+-----+
    

    ずれました。

    マルチバイト文字に対応させてみます。

    formatador-0.2.4/lib/formatador/table.rb

    を以下のように修正しました。

    --- table.rb.org 
    +++ table.rb 
    @@ -1,3 +1,9 @@
    +class String
    +  def width
    +    chars.inject(0){|s,c| s += c.bytesize > 1 ? 2 : 1}
    +  end
    +end
    +
    class Formatador
       def display_table(hashes, keys = nil, &block)
         new_hashes = hashes.inject([]) do |accum,item|
    @@ -14,7 +20,7 @@
         # Calculate Widths
         if hashes.empty? && keys
           keys.each do |key|
    -        widths[key] = key.to_s.length
    +        widths[key] = key.to_s.width
           end
         else
           hashes.each do |hash|
    @@ -52,7 +58,7 @@
         # Display data row
         columns = []
         headers.each do |header|
    -      columns << "[bold]#{header}[/]#{' ' * (widths[header] - header.to_s.length)}"
    +      columns << "[bold]#{header}[/]#{' ' * (widths[header] - header.to_s.width)}"
         end
         display_line("| #{columns.join(' | ')} |")
         display_line(split)
    @@ -80,7 +86,7 @@
       private
    
       def length(value)
    -    value.to_s.gsub(PARSE_REGEX, '').length
    +    value.to_s.gsub(PARSE_REGEX, '').width
       end
    
       def calculate_datum(header, hash)
    

    再度出力してみます。

      +------+-----+
      | name | age |
      +------+-----+
      | 太郎 | 30  |
      | 花子 | 25  |
      +------+-----+
    

    ずれなくなりました!

    環境

    ruby 1.9.3p484

    formatador 0.2.4

    記事を共有