Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

Ruby | CLI | Play Well with Others | Formatting Output for Use As Input Another Program

概要

書籍 Build Awesome Command-Line Applications in Ruby2

Play Well with Others

詳細

あるアプリケーションの出力が他のアプリケーションの入力になる例として、
ls と sort の組み合わせを見る。

ls には数値順にソートする機能はない。
しかし、lsの -1 オプションで1 ファイル 1 行で表示し、
パイプを利用して sort の -n オプションを利用することで要件を満たします。

$ ls -1
1.rb
11.rb
2.rb

$ ls -1 | sort -n
1.rb
2.rb
11.rb

これは、適切な出力フォーマットをサポートすることにより他のアプリケーションと連携して
さらなる機能を得る良い例です。

ここで重要になるUNIXの決まりごとは、行単位の処理です。
必要な情報は1行単位にしておくことで各行に対して次の処理を呼び出すことができます。

悪い出力フォーマットのサンプル

引数1〜引数2の数値の加算を一桁ずつ表示するアプリケーションを作ります。
悪い例では1つの計算結果が2行に分かれています。

人間が見れば意味はわかりますが、仮にこの結果をさらに加工したい場合に想定通りに動いてくれません。

bad.rb

from = ARGV.first.to_i
to = ARGV.last.to_i

(from..to).each_cons(2) do |one, other|
  puts "#{one} + #{other}"
  puts " = #{one + other}"
end
$ ruby bad.rb 1 10
1 + 2
 = 3
2 + 3
 = 5
3 + 4
 = 7
4 + 5
 = 9
5 + 6
 = 11
6 + 7
 = 13
7 + 8
 = 15
8 + 9
 = 17
9 + 10
 = 19

# 降順で sort してみるが思い通りの結果にならない
$ ruby bad.rb 1 12 | sort -nr
11 + 12
10 + 11
9 + 10
8 + 9
7 + 8
6 + 7
5 + 6
4 + 5
3 + 4
2 + 3
1 + 2
 = 9
 = 7
 = 5
 = 3
 = 23
 = 21
 = 19
 = 17
 = 15
 = 13
 = 11

良い出力フォーマットのサンプル

仕様は悪いサンプルと同じ

good.rb

paste_source
$ ruby good.rb 1 12
1 + 2 = 3
2 + 3 = 5
3 + 4 = 7
4 + 5 = 9
5 + 6 = 11
6 + 7 = 13
7 + 8 = 15
8 + 9 = 17
9 + 10 = 19
10 + 11 = 21
11 + 12 = 23

# 降順で sort してみと思い通りの結果になった
$ ruby good.rb 1 12 | sort -nr
11 + 12 = 23
10 + 11 = 21
9 + 10 = 19
8 + 9 = 17
7 + 8 = 15
6 + 7 = 13
5 + 6 = 11
4 + 5 = 9
3 + 4 = 7
2 + 3 = 5
1 + 2 = 3