Scala入門1 Hello World!

集合知のサンプルコードはScalaで書いていこう・・・と意気込み、まずはJSONパーサの作成を試みたのですが、以前勉強会でやっていたこと含めすっかり抜け落ちていたため、入門用の書籍を使って一からやりなおしていくことにしました。

中途半端に覚えてるパターンマッチとか、全て忘れたことにして本当に基本中の基本から。

コマンドラインから Hello World

ScalaにもREPLという対話型の実行環境が備わっています。調べてみると関数型言語では普通に搭載されている機能みたいです。

$ scala
Welcome to Scala version 2.7.7final (Java HotSpot(TM) Server VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.

scala> 

ベタベタに「Hello World!」から書いていきます。

scala> print("Hello World!")
Hello World!

Scalaスクリプトから Hello World

エディタで「.scala」のファイルを作成。

$ vi HelloWorld.scala

先程REPLで実行した一行をそのまま書き込んで保存します。

mainメソッドはスクリプト実行時、Scalaが内部的にラップしてくれるようなので書いていません。

$ scala HelloWorld.scala 
Hello World!

Scalaコードをクラスファイルにコンパイルして Hello World

ScalaJVM上で動作する言語なので、コンパイルしてクラスファイルを作成することができます。

そのためJavaライブラリ等の既存資産を再利用できることもScalaの魅力の一つなのですが、これは今後入門書を読み進めていけば出てくると思います。

試しに作成したばかりのScalaスクリプトをそのままの状態でコンパイルしてみます。

$ scalac HelloWorld.scala 
HelloWorld.scala:1: error: expected class or object definition
print("Hello World!")
^
one error found

怒られた。

ソースコードにクラスかオブジェクトが必要とのことですので、スクリプトの内容をちょっと書き換えてみます。

object HelloWorld {
	def main(args: Array[String]): Unit = {
		println("Hello World!")
	}
}

これでどうだ!

$ scalac HelloWorld.scala 
$ ls
HelloWorld.scala HelloWorld$.class HelloWorld.class

無事コンパイルされ、同ディレクトリにクラスファイルも生成されています。

ではクラスファイルを実行してみましょう。

$ java HelloWorld 
Exception in thread "main" java.lang.NoClassDefFoundError: scala/ScalaObject
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
	at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Caused by: java.lang.ClassNotFoundException: scala.ScalaObject
	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
	... 12 more
Could not find the main class: HelloWorld.  Program will exit.

また怒られた。NoClassDefFoundErrorとな。

ちょっとどうなってるのか分からないので、次回までの宿題としてクラスファイルを逆コンパイルし、中身がどうなっているかを観察してみようと思います。

追記(2011/01/14)

scalacでコンパイルしたクラスファイルはscalaコマンドで実行するようです。

$ scala HelloWorld
Hello World!

javaコマンドで実行するためには、実行時Scalaのライブラリにパスを通してやらないとダメ。

・・・ってこれ、1年ぐらい前に同じ事調べたの思い出しました。

参考

SCALAプログラミング入門

SCALAプログラミング入門