Tbpgr Blog

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

Ruby | CLI | Delight Casual Users | Choosing the Best Default Output Format Based on Context

概要

書籍 Build Awesome Command-Line Applications in Ruby2

Delight Casual Users

詳細

ls はコンテキストに合わせてベストなデフォルト値を適用しています。
ls をオプションなしで、単独実行した場合は
下記のように、人間向けのフォーマットになります。

$ ls
5_delight_casual_users_sample8.yml  hige2  hige4  hige6
hige                                hige3  hige5  hoge/

しかし、パイプラインとともに利用すると下記のようにプログラム向けのフォーマットである

  • 1 オプションを使用した場合と同様の動作になります。
$ ls -1
5_delight_casual_users_sample8.yml
hige
hige2
hige3
hige4
hige5
hige6
hoge/

$ ls | cat
5_delight_casual_users_sample8.yml
hige
hige2
hige3
hige4
hige5
hige6
hoge/

サンプル仕様

下記記事のサンプルの仕様をベースにします。年齢の表示部分のみを利用します。
Ruby | CLI | Be Easy to Use | Thorを利用した使いやすいCommand suitインターフェース
http://d.hatena.ne.jp/tbpg/20140526/1401109675

サンプルコード

require 'csv'
require 'thor'
require 'pp'

class PersonViewer < Thor
  package_name "person_viewer"
  VERSION = "0.0.1"
  PERSONALS = './personals.csv'
  class_option :help, type: :boolean, aliases: '-h', desc: 'ヘルプを表示します'
  class_option :version, type: :boolean, desc: 'バージョンを表示します'

  desc "年齢を表示します", "年齢を表示します"
  option :pretty_print, {type: :boolean, aliases: '-p', desc: "人間向けの出力フォーマットにする"}
  def age
    if options[:pretty_print]
      pritty_print
    else
      puts STDOUT.tty?
      STDOUT.tty? ? pritty_print : machine_print
    end
  end

  desc 'バージョンを表示します', 'バージョンを表示します'
  def version
    puts VERSION
  end

  def self.banner(task, namespace = false, subcommand = true)
      super
  end

  private
    def read_csv
      CSV.table(PERSONALS)
    end

    def pritty_print
      read_csv.each { |row|puts "#{row[:firstname]} #{row[:lastname]}#{row[:age]}歳です" }
    end

    def machine_print
      read_csv.each { |row|puts row[:age] }
    end
end
PersonViewer.start(ARGV)

サンプル出力

# パイプを利用すると machine formatを選択
$ ruby personal.rb a | cat
false
34
54
45

# パイプを利用しないと human formatを選択
$ ruby personal.rb a
true
kazuo tanakaは34歳です
ken satoは54歳です
ichiro suzukiは45歳です

# パイプを利用しても、明示的にオプションを指定すると human formatを選択
$ ruby personal.rb a -p | cat
kazuo tanakaは34歳です
ken satoは54歳です
ichiro suzukiは45歳です