2016-10-28 6 views
1

(Conscriptを使用して)一般的なScalaスクリプトテンプレートを作成したいと思います。このスクリプトでは、冗長モードを有効にするためのコマンドラインオプション、たとえばフラグ "-v"を使用する必要があります。Scalaスクリプトのコマンドラインパラメータを使用するための慣習的な方法

Perlスクリプトでは、グローバル変数$ verboseを作成します。これは、フラグが存在するかどうかによって、trueまたはfalse(または1または0)に設定されます。私は、スクリプト内のグローバル変数を設定することはScalaの方法ではないことを理解しています。それを行うにはどのように

object Main { 
    def main(args: Array[String]) { 
    val options = parseOptions(args); // some way of parsing 

    // how to use 'options' in the remainder of the script? 
    } 
} 

は、次の例を考えてみましょうか?私が見ることのできる1つの方法は、閉包内のコンテキスト変数としてオプション値を保持することです。つまり、入れ子関数からそれらにアクセスします。しかし、ネストされた関数を使用する際の問題は、それらのユニットテストを書くことができないことです。別の簡単な方法は、すべての関数呼び出しと一緒にオプションを渡すことですが、それは扱いにくいようです。

提案がありますか?

答えて

3

解析オプションについては、https://github.com/scopt/scoptを使用できますが、実際にはオプションパーサが返す可能性のあるConfigオブジェクトを使用する方法を尋ねています。

私はConfigオブジェクトを渡す必要があると思います。それを使用するコードの依存関係であり、コードは、グローバル変数を使用するのではなく、できる限り直接依存関係を提供する必要があります。

あなたには、いくつかの入力を保存したい場合は、あなたが、それimplicitlyを渡すことができ、別のモジュールがMain.Configに依存しないように、すなわち

case class Config(verbose: Boolean) 

object Main { 
    def main(args: Array[String]) { 
    implicit val config: Config = parseOptions(args); // some way of parsing 

    new FooComponent().doSomeStuff() 
    } 
} 

class FooComponent()(implicit config: Config) { 

    def doSomeStuff() { 
    ... stuff 
    if (config.verbose) { 
     println(...) 
    } 
    ... 
    } 
} 

あなたはまた、IoCのパターンを使用することができますが、代わりに公開Configが実装する必要がある設定を宣言するインタフェース。

すなわち

case class Config(verbose: Boolean) extends FooHandler.Config { 
    def printFooInfo: Boolean = verbose 
} 

object Main { 
    def main(args: Array[String]) { 
    val config: Config = parseOptions(args); // some way of parsing 

    FooHandler.handleFoo(config) 
    } 
} 

// This looks contrived with small code, but works well if 
// your codebase is large and FooHandler is far away from Main 
object FooHandler { 
    trait Config { 
    def printFooInfo: Boolean 
    } 

    def handleFoo(config: Config) { 
    ... stuff 
    if (config.printFooInfo) { 
     println(...) 
    } 
    ... 
    } 
} 
+0

感謝。それでは、scoptのOptionParser.parse()関数が返すconfigオブジェクトをどうやって使うのですか? –

+0

答えを更新して、これがリンクオンリーの回答であることを避ける方法の例を投稿してください – Daenyth

+0

ありがとう、私は_implicit_を使用しているバージョンは私の場合は非常にうまくいくと思います! –

関連する問題