小さいアプリをらくらく書く試み

仕事で直接的にrubyを使う案件はないんだけども、データを加工したりする小さなツールは大体rubyで作っている。らくらくだ。


どれも、だいたい

  • オプション解析
  • 本処理

な流れで作ってる感じ。最初に作った物をコピペコピペで使いまわしてるので、まあ似るんだけど。


なんともめんどくさいのはオプション解析。
今までコピペで使いまわしてきたけど、思い立って、楽できるようなライブラリを作ってみた。


んだけども、まだまだ洗練されていない。
ただ、洗練させることに力を注ぎすぎてもあれだ。


とゆうか、既にありそう。
んでもSimpleConsoleは試したけど肌に合わなかった。


こんな感じに書ける

# sample.rb
require "miniappbase"

class Test < MiniAppBase
  def_option \
    "--hoge",
    :arg => "HOGE_HOGE", 
    :short => "-h",
    :description => "Sample Option Hoge.",
    :default => "this is default value"
  def_option \
    "--fuga", 
    :arg => "[FUGA_FUGA]", 
    :short => "-f",
    :description => "Sample Option Fuga.",
    :default => "this is default value"
  
  def main(args, options, help)
    p args
    p options
    print help
  end
end

Test.run(ARGV)


実行結果

$ ruby test.rb test_arg --hoge aaa --fuga bbb
["test_arg"]
{"--fuga"=>"bbb", "--hoge"=>"aaa"}
Usage: test [options]
    -h, --hoge HOGE_HOGE             Sample Option Hoge.
    -f, --fuga [FUGA_FUGA]           Sample Option Fuga.

$ ruby test.rb test_arg_1 test_arg_2 -h aaa
["test_arg_1", "test_arg_2"]
{"--fuga"=>"this is default value", "--hoge"=>"aaa"}
Usage: test [options]
    -h, --hoge HOGE_HOGE             Sample Option Hoge.
    -f, --fuga [FUGA_FUGA]           Sample Option Fuga.


こんなソース。手抜き。

# miniappbase.rb
require "optparse"

class MiniAppBase
  @@optparse = OptionParser.new
  @@options = {}
  
  def self.run(argv)
    self.new.run(argv)
  end
  
  def self.def_option(long, optional_params = {})
    args = []
    if optional_params[:default]
      @@options[long] = optional_params[:default]
    end
    unless optional_params[:arg]
      args << long
    else
      args << "#{long} #{optional_params[:arg]}"
    end
    args << optional_params[:short]
    args << optional_params[:description]
    args.compact!
    @@optparse.def_option(*args) do |v|
      @@options[long] = v
    end
  end
  
  def run(argv)
    @@optparse.permute!(argv)
    main(argv, @@options, @@optparse.help)
  rescue OptionParser::InvalidOption
    #未定義のオプションは無視
  end
  
  def main(args, options, help)
  end
end


mainの引数helpは、微妙。いらない気も。
"--help"渡せばhelp出るし。