VB2008でコマンドライン スイッチの判定を実装してみた
http://devadjust.exblog.jp/20069155/
この記事を見て、久々に何か書いてみたいな!と思ったので、書いてみます。
まず、コマンドライン引数のパーサを書くんだけど、パースした結果をどう扱えるか? どれだけ扱いやすいか? という事から考えてみた。私なら、こう書きたい。
Dim opts = (New OptionParser).Parse(args) 'この辺はきっとごにょごにょする Dim hogeParam1 As String = "hogedefault1" 'set default Dim hogeParam2 As String = "hogedefault2" 'set default If opts.ContainsKey("hoge") Then 'こんな感じで「このパラメータあれば」って書けるとうれしい With opts("hoge") 'VB風味を加える If .Count >= 1 Then '個別の引数はこんな感じで hogeParam1 = .Item(0) End If If .Count >= 2 Then hogeParam2 = .Item(1) End If End With End If
こんな感じでスイッチの部分はディクショナリのキーになってて、そのスイッチの引数はディクショナリの値(コレクション)に要素として入ってる。きっと書くときこうなってると嬉しい感じがする。で、これをやってくれるOptionParserを書いた。
Public Class OptionParser Private listOfOptionName As New List(Of String) Private swChar As Char Public Sub New(ByVal args() As String, ByVal swc As Char) swChar = swc listOfOptionName = args.Distinct().ToList() End Sub Public Function Parse(ByVal args() As String) As Dictionary(Of String, List(Of String)) Parse = New Dictionary(Of String, List(Of String)) For i = 0 To args.Length - 1 Dim targetArg = args(i) If listOfOptionName.Exists(Function(n) String.Format("{0}{1}", swChar, n) = targetArg) Then Parse.Add(targetArg.Substring(1, targetArg.Length - 1), New List(Of String)) Else If Parse.Count > 0 AndAlso targetArg(0) <> swChar Then Parse.Last.Value.Add(targetArg) Else Debug.Print("{0} droped.index={1}", targetArg, i) End If End If Next End Function End Class
呼ぶときはこんな感じに。
Sub Main(ByVal args() As String) Dim myOptions() As String = {"hoge", "fuga", "piyo"} Dim opts = (New OptionParser(myOptions, "-"c)).Parse(args)
コンストラクタの第二引数に"-"cとか書いてあるのは、ほら、あれですよ、スイッチって"/"のコマンドとかもあるじゃないですか。そこらへんのフィーリングに引数ひとつで対応する為。考えすぎかもしれないけど。
呼び出し部分全体を、もっかい貼り付けてみよう。
Module OptionParseSample Sub Main(ByVal args() As String) Dim myOptions() As String = {"hoge", "hoge", "fuga", "piyo"} Dim opts = (New OptionParser(myOptions, "-"c)).Parse(args) 'パースした結果を出力 For Each item In opts Console.WriteLine(item.Key) For Each p In item.Value Console.WriteLine(" {0}", p) Next Next 'こんな風に書けるよ! Dim hogeParam1 As String = "hogedefault1" 'set default Dim hogeParam2 As String = "hogedefault2" 'set default If opts.ContainsKey("hoge") Then With opts("hoge") If .Count >= 1 Then hogeParam1 = .Item(0) End If If .Count >= 2 Then hogeParam2 = .Item(1) End If End With End If End Sub End Module
お楽しみでほいほいーっと書いたので、テキトーにバグってるかもしんない(予防線)。でもまあ、OKだ。初めてGitHubにリポジトリも作ってアップしちゃったー! きゃー!w
でも、このリポジトリへのリンクとかどうやって貼るんだろ? ま、それはあとで勉強しよう。ひとまず送信!