20518


scala コマンドで *.scala ファイルをスクリプトのように実行する場合の、  
クラス定義の書き方について質問させてください。

[code]

    // a.scala
    object Main {
      def main(args: Array[String]) {
        println("hello")
      }
    }
    
[/code]

上の a.scala ファイルを scala コマンドで実行すると、main メソッドが呼び出されて  
hello と表示されます。

[code]

    $ scala a.scala
    hello
    
[/code]

次に a.scala にクラス Foo の定義を追加すると、今度は main メソッドが呼び出されなくなります。

[code]

    // a.scala
    class Foo {} // クラス定義を追加する
    
    object Main {
      def main(args: Array[String]) {
        println("hello")
      }
    }
    
[/code]

scala コマンドで実行してみると、main メソッドが呼ばれなくなりました。

[code]

    $ scala a.scala
    $ # 何も表示されない
    
[/code]

以下の方法ですと、main メソッドが実行されることは確認しています。

  * scalac コマンドでコンパイルしてから、scala Main を実行
  * クラス Foo の定義を、Main の中で定義する

質問なのですが、Main の外でクラス Foo を定義して、  
scala a.scala で main メソッドを呼ぶ方法はないのでしょうか？


CC BY-SA 3.0
2015-12-31T14:41:16.703
20514
2016-01-01T07:34:49.177
13856
question
scala
Scala: クラス定義を追加すると、scala コマンドで main メソッドが実行されなくなる


最後に  
`Main.main(args)`  
を追加して書いて明示的に呼び出す。


CC BY-SA 3.0
2015-12-31T14:59:55.257
20515
2015-12-31T14:59:55.257
5044
20514
answer


## 方法1

`scalac`でコンパイルして実行する  
<http://www.scala-lang.org/documentation/getting-started.html#compile-it>

[code]

    > scalac a.scala
    > ls
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    -a----       2016/01/01     14:13            122 a.scala
    -a----       2016/01/01     14:13            474 Foo.class
    -a----       2016/01/01     14:13            608 Main$.class
    -a----       2016/01/01     14:13            546 Main.class
    
    > scala Main
    hello
    
[/code]

## 方法2

`scala`コマンドはコードをスクリプトとして実行します。  
そしてコードがmainメソッドのあるclassまたはobjectだけの場合は、mainメソッドを自動で実行してくれます。

**類似の質問への回答**  
<https://stackoverflow.com/a/16993075/4366193>

今回のようなコードでは`object Main`と`class Foo`の定義のみでスクリプトが終了し、mainメソッドは自動で実行されません。  
BLUEPIXYさんの回答のように明示的に`Main.main(args)`を呼び出せば実行されます。

[code]

    class Foo {}
    
    object Main {
      def main(args: Array[String]) {
        println("hello")
      }
    }
    
    Main.main(args)
    
[/code]

## 方法3

方法2をふまえると`object Main`だけがトップレベルで定義されていればmainメソッドが自動で実行されますので、`object
Main`内に`class Foo`を定義する方法があります。

[code]

    object Main {
      def main(args: Array[String]): Unit = {
        Foo.hello()
      }
    
      class Foo
    
      object Foo {
        def hello(): Unit = {
          println("hello")
        }
      }
    }
    
[/code]


CC BY-SA 3.0
2016-01-01T06:27:25.083
20518
2016-01-01T06:48:51.507
2017-05-23T12:38:55.250
-1
3068
20514
answer


ソースコードを変更したくない場合は、以下の様にすると良いかと思います。

[code]

    $ scala -i a.scala -e 'Main.main(args)'
    
[/code]

その他には sbt を使う方法もあります。

[code]

    $ sbt 'run-main Main'
    
[/code]


CC BY-SA 3.0
2016-01-01T07:34:49.177
20519
2016-01-01T07:34:49.177
20514
answer