Scala はじめるはじめる詐欺をしていたので、はじめることにしました。
インストール
Gentoo Prefix で
emerge dev-lang/scala
と、しましたが、ビルドに失敗しました。 ドキュメントまわりでエラーのようなのでちょっと工夫すればビルドできそうですが、諦めてバイナリインストールを試みました。
$EPREFIX/etc/partoge/pacakeg.use
に以下を加えました。
=dev-lang/scala-2.9.2 binary
はじめてみる
Getting Started - Scala を参考にはじめてみました。 基本のハローワールドです。ようこそ Scala の世界へ。
scala
コマンドで対話環境が起動できます。
$ scala
そこに以下のコードを打ち込んでみました。
object HelloWorld {
def main(args: Array[String]) {
println("Hello, world!")
}
}
僕の Ruby 的な感覚では HelloWorld というオブジェクトを作り特異メソッド main を定義している感じに見えます。 このあたりは、Java のエントリポイントが static な main メソッドになるのを知っていれば、納得感はあります。
対話環境には
defined module HelloWorld
と表示されているのが気になります。 「オブジェクトは別にメソッドが集めるところが用意されてるのかな?」という印象を受けました。
その後、追加で、
HelloWorld.main(null)
と入力しますと、Hello, World
と出力されました。
Haskell を学習してる感覚からいくと 第1引数は null より空のリストを渡したいですね。 「null が渡せて気持ち悪い。」的な感じがしました。 オブジェクトは null をはじめから許容していると考えれば、大丈夫そうです。 リストではなく配列という種類のオブジェクトなのでしょう。
終了するには :q
を入力するようです。 C-d
も終了できました。
コンパイルしてみる
さきほどは、対話環境で入力して確認してみましたが、次はコンパイルしてみるようです。
プログラムのソースコードの拡張子は scala
を使うようです。
scalac
コマンドでコンパイルできるそうです。
なので、HelloWorld.scala
というファイルを作成してさきほどのソースコードを貼りつけて、
scalac HelloWorld.scala
としました。
作成されたファイルは
- HelloWorld$.class
- HelloWorld.class
でした。
実行には
scala HelloWorld
とするようです。
試しに、
java HelloWorld
とすると scala/ScalaQbject がみつからない
というエラーになりました。
上手いこと 指定してやれば実行できるそうですね。
そもそも scala
コマンドはシェルスクリプトで java を上手いこと起動してる感じのようでした。
あと Hello.scala
でも問題なくコンパイルできるようです。
こういうことをしていると余計なトラブルに巻き込まれる感がありそうです。
ついでに、sacala Hello.scala
としても実行できました。しかし、遅い。
まとめ
Scala で遊ぶ準備ができました。 次はエディタ環境を整えたいです。
sacala と typo しやすい。 対策を練りたい。
もうちょっと遊びたい。次は何を読みながら試すのがよいのだろうか。
追記
謎の暗号が飛んできた。
```scala object HelloWorld extends App { println("Hello, world!") } HelloWorld.main(null) ``` とかいても良いらしい。 Ruby 脳で考えると、クラスコンテキストに書いた部分がまるまる main メソッドの中にはいっている感。 どういう仕組みになっているのか調べるのには何を見ればいいのだろうか。App traitやでひむひむ
— 航空母艦 (@razon) August 17, 2013
— 航空母艦 (@razon) August 17, 2013
的確なヒントが飛んでくる。
http://www.scala-lang.org/api/current/index.html#scala.App
https://github.com/scala/scala/blob/v2.10.2/src/library/scala/App.scala#L59-L61 https://github.com/scala/scala/blob/v2.10.2/src/library/scala/App.scala#L71
あたりが怪しい。
override def delayedInit(body: => Unit) {
initCode += (() => body)
}
def main(args: Array[String]) = {
this._args = args
for (proc <- initCode) proc()
if (util.Properties.propIsSet("scala.time")) {
val total = currentTime - executionStart
Console.println("[total " + total + "ms]")
}
あらかじめ main メソッドを定義しておいて、処理を追加できる感じがします。
delayedInit がどうやって hook されるかは DelayedInit を追えばなにか分かる臭がしますね。
引数は args で取れそう。
object HelloWorld extends App {
println(args(0))
}
HelloWorld.main(Array("hoge"))
まだまだ、わからないことがたくさんあるけど、魔法みたいなことができることを知る。