コマンドライン引数の解析

コマンドライン引数を解析します。


※ モードを使用する場合など、同じ名前の引数が存在すると、GHCのキャッシュのため、アノテーションが
 有効にならい。{-# OPTIONS_GHC -fno-cse #-}プラグマを付けると解消できる。 

簡単な例


{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Guess = Guess {
              min   :: Int
            , max   :: Int
            , limit :: Maybe Int
            } deriving (Data,Typeable,Show)

main = do
  guess <- cmdArgs $ Guess 1 100 Nothing
  print guess


引数解析用のデータ型を定義して、cmdArgs関数にデフォルトデータを渡します。
これで、引数値をセットしたデータを返してくれます。

> runghc sample1.hs -?
The guess program

guess [OPTIONS]

Common flags:
     --min=INT
     --max=INT
  -l --limit=INT
  -? --help       Display help message
  -V --version    Print version information

>


cmdArgs関数を利用するだけで、上記のような一般的なコマンドラインヘルプを表示できます。
実際にオプションを指定して実行してみましょう。


> runghc sample1.hs

Guess {min = 1, max = 100, limit = Nothing}

>
> runghc sample1.hs --min=-10 --max=10 -l 100

Guess {min = -10, max = 10, limit = Just 100}

>
>


データ型のレコードとして使用できる型

  • String, Int, Integer, Float, Double, Bool,
  • an enumeration
  • a tuple of atomic types
  • list ([]) atomic type
  • Maybe wrapping at atomic type

Annotations

コマンドライン引数の各オプションの詳細な設定は、Annotationで指定します。
Annotationは、「&=」演算子で設定します。

opt アノテーション

オプション値をoptionalにします。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello = "default world" &= opt "optional world"
       }

main = cmdArgs config >>= print



> runghc sample2_opt.hs -?
The sample program

sample [OPTIONS]

Common flags:
  -h --hello[=ITEM]
  -? --help          Display help message
  -V --version       Print version information

> runghc sample2_opt.hs
Sample {hello = "default world"}

> runghc sample2_opt.hs --hello=world
Sample {hello = "world"}

> runghc sample2_opt.hs --hello
Sample {hello = "optional world"}

>


optアノテーションでは、「--hello」オプションが指定されたが値が指定されなかった場合の値を設定できます。


typ アノテーション

ヘルプ表示の各オプション値の表記を設定します。
デフォルトでは、「ITEM」です。

Common flags:
  -h --hello[=ITEM]    <-- これ


{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello  :: String
            , outDir :: String
            , input  :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello  = "default world" &= typ "MESSAGE"
       , outDir = "/tmp"          &= typDir
       , input  = "hello.csv"     &= typFile
       }

main = cmdArgs config >>= print

> runghc sample3_typ.hs -?
The sample program

sample [OPTIONS]

Common flags:
  -h --hello=MESSAGE
  -o --outdir=DIR
  -i --input=FILE
  -? --help           Display help message
  -V --version        Print version information

>


typDir と typFileアノテーションは、typ "DIR"、typ "FILE" へのAliasです。


help アノテーション


ヘルプ表示の各オプションの説明を設定します。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello  :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello  = "default world" &= help "Help message"
       }

main = cmdArgs config >>= print



> runghc sample4_help.hs -?
The sample program

sample [OPTIONS]

Common flags:
  -h --hello=ITEM  Help message                     <-- これ
  -? --help        Display help message
  -V --version     Print version information

>



name アノテーション


オプションに別名を用意します。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello  :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello  = "default world" &= name "foo"
       }

main = cmdArgs config >>= print



> runghc sample5_name.hs -?
The sample program

sample [OPTIONS]

Common flags:
  -f -h --foo=ITEM --hello
  -?    --help              Display help message
  -V    --version           Print version information

> runghc sample5_name.hs -h world
Sample {hello = "world"}

> runghc sample5_name.hs -f world
Sample {hello = "world"}

> runghc sample5_name.hs --foo=world
Sample {hello = "world"}

>


「--hello」 オプションに対して、「--foo」も使用できます。



explicit アノテーション

nameアノテーションと共に使用します。
nameアノテーションで設定したオプション名だけを使用できるようになります。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello   :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello  = def &= explicit &= name "foo"
       }
       
main = cmdArgs config >>= print



> runghc sample11_explicit.hs -?
The sample program

sample [OPTIONS]

Common flags:
     --foo=ITEM                           <-- helloフラグがない
  -? --help      Display help message
  -V --version   Print version information

>




args アノテーション


フラグ無しオプションに設定します。
複数のフラグ無しオプションを利用する場合は、次のargPosアノテーションを使用します。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello  :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello  = "default world" &= args
       }

main = cmdArgs config >>= print



> runghc sample6_args.hs -?
The sample program

sample [OPTIONS] [ITEM]

Common flags:
  -? --help     Display help message
  -V --version  Print version information

>



argPos アノテーション



複数のフラグ無しオプションを、順番付けして設定します。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              input   :: String
            , output  :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         input  = def &= typ "IN"  &= argPos 0
       , output = def &= typ "OUT" &= argPos 1
       }

main = cmdArgs config >>= print


> runghc sample7_argPos.hs -?
The sample program

sample [OPTIONS] IN OUT

Common flags:
  -? --help     Display help message
  -V --version  Print version information

>


argPosアノテーションを設定すると、その引数はデフォルト値が設定されていても必須引数になります。


groupname アノテーション

ヘルプ表記の際に、オプションをグルーピングして表示します。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello   :: String
            , input   :: String
            , output  :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello  = def &= groupname "FIRST"
       , input  = def &= groupname "SECOND"
       , output = def
       } &= helpArg [groupname "THIRD"]

main = cmdArgs config >>= print



> runghc sample8_group.hs -?
The sample program

sample [OPTIONS]

FIRST:
  -h --hello=ITEM
SECOND:
  -i --input=ITEM
  -o --output=ITEM
THIRD:
  -? --help         Display help message
  -V --version      Print version information

>



summary, details アノテーション

ヘルプの先頭に表示するサマリーと、ヘルプの最後に表示する詳細情報を設定します。
サマリーは1文字列。 詳細情報は複数文字列。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello   :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello  = def
       } &= summary "hello summary"
         &= details ["sample detail", "second line"]
       
main = cmdArgs config >>= print


summaryとdetailsアノテーションは、共にMode (Sample) に対して設定します。

> runghc sample9_detail.hs -?
hello summary

sample [OPTIONS]

Common flags:
  -h --hello=ITEM
  -? --help        Display help message
  -V --version     Print version information

sample detail
second line

>



program アノテーション

ヘルプ表記のプログラム名を設定します。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello   :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello  = def
       } &= program "hello_program_name"
       
main = cmdArgs config >>= print



> runghc sample10_program.hs -?
The hello_program_name program

hello_program_name [OPTIONS]               <-- これ

Common flags:
  -h --hello=ITEM
  -? --help        Display help message
  -V --version     Print version information

>



ignore アノテーション

ignoreアノテーションが付いたレコードは無視されます。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello   :: String
            , world   :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello = def
       , world = def &= ignore
       }
       
main = cmdArgs config >>= print



> runghc sample12_ignore.hs -?
The sample program

sample [OPTIONS]

Common flags:
  -h --hello=ITEM
  -? --help        Display help message
  -V --version     Print version information

>



verbosity アノテーション

verboseとquietオプションを追加します。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello   :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello = def
       } &= verbosity
       
main = cmdArgs config >>= print



> runghc sample13_verbosity.hs -?
The sample program

sample [OPTIONS]

Common flags:
  -h --hello=ITEM
  -? --help        Display help message
  -V --version     Print version information
  -v --verbose     Loud verbosity
  -q --quiet       Quiet verbosity

>



helpArg アノテーション

デフォルトで表示されるヘルプオプションをカスタマイズします。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello   :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello = def
       } &= helpArg [name "foo"]
       
main = cmdArgs config >>= print



> runghc sample14_helpArg.hs -?
The sample program

sample [OPTIONS]

Common flags:
  -h --hello=ITEM
  -? --foo --help  Display help message
  -V --version     Print version information

>



versionArg アノテーション

デフォルトで表示されるバージョンオプションをカスタマイズします。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello   :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello = def
       } &= versionArg [name "foo"]
       
main = cmdArgs config >>= print



> runghc sample15_versionArg.hs -?
The sample program

sample [OPTIONS]

Common flags:
  -h --hello=ITEM
  -? --help           Display help message
  -V --foo --version  Print version information

>



verbosityArgs アノテーション


verbosityアノテーションを使用した場合の表示をカスタマイズします。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = Sample {
              hello   :: String
            } deriving (Data,Typeable,Show)

config = Sample {
         hello = def
       } &= verbosityArgs [name "foo"] [name "bar"]
       
main = cmdArgs config >>= print



> runghc sample16_verbosityArgs.hs -?
The sample program

sample [OPTIONS]

Common flags:
  -h --hello=ITEM
  -? --help           Display help message
  -V --version        Print version information
  -v --foo --verbose  Loud verbosity
  -q --bar --quiet    Quiet verbosity

>


modes, auto アノテーション

modesは複数のモードを設定します。
autoアノテーションは、modesの中でデフォルトモードを設定します。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data Sample = SampleA {
              hello   :: String
            } |
              SampleB {
              input :: String
            , output :: String            
            } deriving (Data,Typeable,Show)

configA = SampleA {
         hello = def
       } &= name "commandA" &= auto 

configB = SampleB {
         input  = def
       , output = def
       } &= name "commandB"
       
config = modes [configA, configB]

main = cmdArgs config >>= print



> runghc sample17_mode.hs -?
The sample program

sample [COMMAND] ... [OPTIONS]

Common flags:
  -? --help         Display help message
  -V --version      Print version information

sample [commandA] [OPTIONS]

  -h --hello=ITEM

sample commandB [OPTIONS]

  -i --input=ITEM
  -o --output=ITEM

>



モード毎にヘルプが表示できます。

> runghc sample17_mode.hs commandA -?
The sample program

sample [commandA] [OPTIONS]

Flags:
  -h --hello=ITEM
Common flags:
  -? --help        Display help message
  -V --version     Print version information

>
> runghc sample17_mode.hs commandB -?
The sample program

sample commandB [OPTIONS]

Flags:
  -i --input=ITEM
  -o --output=ITEM
Common flags:
  -? --help         Display help message
  -V --version      Print version information

>



モード毎の実行

> runghc sample17_mode.hs       <-- モード省略。 autoで設定したモードが実行される。
SampleA {hello = ""}

>
> runghc sample17_mode.hs commandA
SampleA {hello = ""}

>
> runghc sample17_mode.hs commandB -i "a.txt" -o "z.txt"
SampleB {input = "a.txt", output = "z.txt"}

>



enum

オプション値として enum を使用します。

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs

data State = On | Off deriving (Data,Typeable,Show)
 
data Sample = Sample {
              state :: State
            } deriving (Data,Typeable,Show)

config = Sample {
         state = enum [On &= help "Turn on",Off &= help "Turn off"]
       }

main = cmdArgs config >>= print



> runghc sample18_enum.hs -?
The sample program

sample [OPTIONS]

Common flags:
     --on       Turn on
     --off      Turn off
  -? --help     Display help message
  -V --version  Print version information

>





Comments