[Ruby] ruby で ARGV をうけるコマンドっぽいものを作ってみる

memo.

[markdown]
## ARGV をうけとってコマンドっぽく動かす

キチンと書くとどうなるのかググってみた所、下記の書籍のコードを見つけました。

Rubyアプリケーションプログラミング
前田 修吾 まつもと ゆきひろ やまだ あきら 永井 秀利
オーム社
売り上げランキング: 106,912

以前の知識を元に、行頭にパスを付けて `chmod +x` してみる。

“`ruby:argv_cmd.rb
#!/usr/bin/ruby
if ARGV.size < 2 STDERR.print "Usage: ruby#{$0} user_name password [server]\n" exit end puts user_name = ARGV[0] puts password = ARGV[1] puts server = if ARGV[2] then ARGV[2] else 'localhost' end ``` ```prettyprinted % chmod +x argv_cmd.rb ``` 実行してみる。 ```prettyprinted % ./argv_cmd.rb bob tatata iris bob tatata iris ``` ## optparse をつかって -a のようなコマンドラインオプションをつかう OptionParser を使うとよいことが分かったので、さらに調べてみる。 > * [library optparse](http://docs.ruby-lang.org/ja/2.1.0/library/optparse.html)
> * [Rubyでコマンドの中身を作るまで – ザリガニが見ていた…。](http://d.hatena.ne.jp/zariganitosh/20100210/1265785723)

“`ruby
#!/usr/bin/ruby
require ‘optparse’
parser = OptionParser.new
parser.version = ‘0.0.1’
parser.on(‘-u user’, ‘–user’) {|v| OPTS[:u] = v}
parser.on(‘-p password’, ‘–password’) {|v| OPTS[:p] = v}
parser.on(‘-s [server]’, ‘–server’) {|v| OPTS[:s] = v}
parser.parse!(ARGV)
p ARGV[0]
p OPTS
“`

実行。

“`prettyprinted
% ./argv_cmd.rb -s iris -u bob -p tatata filename
“filename”
{:s=>”iris”, :u=>”bob”, :p=>”tatata”}
“`

さらにディフォルトで、`–help` や `–version` に対応しているとのこと。

“`prettyprinted
% ./argv_cmd.rb –help
Usage: argv_cmd [options]
-u, –user user
-p, –password password
-s, –server [server]
% ./argv_cmd.rb –version
argv_cmd 0.0.1
“`

おぉ!!

### ARGV.getopts をつかう

と手軽に書けるよう。初期値もかけた。

“`ruby
#!/usr/bin/ruby
require ‘optparse’
OPTS = ARGV.getopts(”, ‘user:’, ‘password:’, ‘server:localhost’)
p ARGV[0]
p OPTS
“`

実行。

“`prettyprinted
% ./argv_cmd.rb -s iris -u bob -p tatata filename
“filename”
{“user”=>”bob”, “password”=>”tatata”, “server”=>”iris”}
% ./argv_cmd.rb –help
Usage: argv_cmd [options]
–user VAL
–password VAL
–server VAL
“`

> * [Ruby – ARGVの処理にOptionParserを使ってるライバルをバックミラーから高速に消し去るARGV.getoptsの使い方 – Qiita](http://qiita.com/genta/items/785900055a5be2ba5d2c)

## エラー時にヘルプを表示する

こちらを参考に、エラーを拾ったらヘルプを表示するよう処理。

> * [optparseライブラリを使う(in Ruby) | 雑記帳](http://cosmo0920.wordpress.com/2011/06/13/optparse%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%82%92%E4%BD%BF%E3%81%86in-ruby/)

“`ruby
OPTS = {}
OptionParser.new do |opt|
begin
opt.version = ‘0.0.1’
opt.on(‘-u VAL’, ‘–user’, ‘user’) {|v| OPTS[:u] = v}
opt.on(‘-p VAL’, ‘–password’, ‘password’) {|v| OPTS[:p] = v}
opt.on(‘-s [VAL]’, ‘–server’, ‘server name’) {|v| OPTS[:s] = v}
opt.on(‘-h’,’–help’,’show this message’) {puts opt; exit}
opt.parse!(ARGV)
rescue => e
puts “ERROR: #{e}.\nSee #{opt}”
exit
end
end
“`

## ヘルプの見栄えを整える

いろいろがんばってみる。

> * [class OptionParser](http://docs.ruby-lang.org/ja/2.1.0/class/OptionParser.html)

“`prettyprinted
% ./argv_cmd.rb –help
Usage: argv_cmd.rb [options] file.csv
Examples:
% argv_cmd.rb -u foo -p bar -s buzz file.csv
Specific options:
-u, –user USER user
-p, –password PASSWORD password
-s, –server SERVER server
Common options:
-h, –help show this help message and exit
-v, –version show program’s version number and exit
“`

ぽい感じになった!

> * [How can I get the name of the command called for usage prompts in Ruby? – Stack Overflow](http://stackoverflow.com/questions/4834821/how-can-i-get-the-name-of-the-command-called-for-usage-prompts-in-ruby)
> * [Get Filename from file path in Ruby – Stack Overflow](http://stackoverflow.com/questions/374326/get-filename-from-file-path-in-ruby)

## 補遺

> * [RubyのブロックとかOptionParserの話(was: 大江戸Ruby会議04のスレ) – qwik.jp/asakusarb](http://qwik.jp/asakusarb/309.html)
> * [Zsh – シェルスクリプトのオプション設計ガイドライン – Qiita](http://qiita.com/mollifier/items/95a294f95f5977b9d663)
> * [RubyのOptionParserの底力を知る – ザリガニが見ていた…。](http://d.hatena.ne.jp/zariganitosh/20140819/ruby_optparser_true_power)
[/markdown]