LoginSignup
1

More than 5 years have passed since last update.

jessevdk/go-flagsを使ってみる

Last updated at Posted at 2014-08-15

はじめに

pecoを使ってみて、どう実装しているのか気になったのでソースコードを読み始めました。まだ読み始めたばかりなので、全然理解できていないのですが、pecoで使われているjessevdk/go-flagsを使ってみたので、それについて書きたいと思います。内容としては、お試しで実装して動かしたことと、読んだドキュメントの紹介になります。

実装

sample.go
package main

import (
    "fmt"

    "github.com/jessevdk/go-flags"
)

type cmdOptions struct {
    OptHelp           bool   `short:"h" long:"help"`
    OptTTY            string `long:"tty"`
    OptQuery          string `long:"query"`
    OptRcfile         string `long:"rcfile"`
    OptNoIgnoreCase   bool   `long:"no-ignore-case"`
    OptVersion        bool   `long:"version"`
    OptBufferSize     int    `long:"buffer-size" short:"b"`
    OptEnableNullSep  bool   `long:"null"`
    OptInitialIndex   int    `long:"initial-index"`
    OptInitialMatcher string `long:"initial-matcher"`
    OptPrompt         string `long:"prompt"`
}

func main() {
    var err error

    // fmt.Print("Start\n")

    opts := &cmdOptions{}
    p := flags.NewParser(opts, flags.PrintErrors)
    args, err := p.Parse()
    if err != nil {
        fmt.Print("Error\n")
        return
    }

    if 0 < len(args) {
        fmt.Print(args[0] + "\n")
    }

    if opts.OptHelp {
        fmt.Print("OptHelp\n")
    }
    if opts.OptVersion {
        fmt.Print("OptVersion\n")
    }
    if opts.OptRcfile != "" {
        fmt.Print("OptRcfile: " + opts.OptRcfile + "\n")
    }
    if opts.OptNoIgnoreCase {
        fmt.Print("OptNoIgnoreCase\n")
    }
    if opts.OptInitialMatcher != "" {
        fmt.Print("OptInitialMatcher: " + opts.OptInitialMatcher + "\n")
    }
    if opts.OptQuery != "" {
        fmt.Print("OptQuery: " + opts.OptQuery + "\n")
    }
    if opts.OptPrompt != "" {
        fmt.Print("OptPrompt: " + opts.OptPrompt + "\n")
    }

    // fmt.Print("End\n")
}

試し方

まず、パッケージが必要になると思いますので、次のコマンドを実行します。

$ go get github.com/jessevdk/go-flags

次に、実行ファイルを作成するために、次のコマンドを実行します。

$ go build sample.go

ここまでの作業で、ソースファイルと同じフォルダに実行ファイルが作成されたと思います。ここではsampleという実行ファイルが作成されると思います。あとは、いろいろなオプションで実行ファイルを実行するだけです。しかし、どんなオプションで実行すれば試せるのでしょうか?

どんなコマンドラインのオプションがこの実行ファイルにあるのか?

お試し実装の構造体の宣言のところなのですが、フィールドの宣言でバッククォートを使っています。これは未加工文字列リテラルで、バッククォート内の文字列シーケンスをそのまま使うものです。例えば、バックスラッシュをそのままバックスラッシュとして使います。

このバッククォートのところをよく見てみると、コマンドラインのオプションを定義しているように見えます。例えば、-h--helpというオプションを-p--printにしたければ、次のようにソースファイルを編集すれば良さそうです。

-   OptHelp           bool   `short:"h" long:"help"`
+   OptHelp           bool   `short:"p" long:"print"`

C++言語の構造体を想像していたので、こういうことができるとは思っていませんでした。ぐぐってみると、Go言語仕様翻訳(part5)に次のようにありました。

フィールドの宣言には、オプションで文字列リテラルを使ってタグを指定することができます。タグはそれが記述されているフィールド宣言の全フィールドの属性となります。タグはリフレクションインタフェースを使って参照できますが、それ以外は無視されます。

ここまでの話で、おそらく、どんなコマンドラインのオプションがこの実行ファイルにあるのか読み解くことができるようになったと思います。時間のある方は確認してみてください。。。

まとめ

Go言語を触りながら、clib の使い勝手にマジ感動したを思い出していました。github上にあるパッケージを手軽に利用できるというのは嬉しいですね。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1