Scalaは、オブジェクト指向と関数型というそれぞれの要素を兼ね備えた設計がされているスクリプト言語とその実装(処理系)です。スイス連邦工科大学ローザンヌ校(EPFL)のMartin Odersky教授によって、2001年から設計が開始されました。最初の実装がリリースされたのは2003年です。これから紹介するバージョン2.6.0-finalのリリースは、2007年9月11日でした。
Scalaで開発されているプロダクトとして、Webフレームワークのlife、テストツールのRehersalやScalaCheck、振る舞い駆動設計(Behaviour-Driven-Design)フレームワークのspecsなどが挙げられます。また、ビルドツールMavenのScalaプラグインも存在します。
Scalaの実装は学内のProgramming Methods Laboratory(LAMP)を中心に行われています。配布ライセンスはBSDライクのScala Licenseです。実行にはJDK1.4以降が必要となります。
Java VM上で動作するスクリプト言語としては、JRubyやJythonなどいくつかありますが、Scalaもそれらと同じようにコマンドラインシェル上で入力したソースコードを、コンパイルの手順を踏まずに実行することができます。一方で、ソースコードをJavaのclassファイルにコンパイルしてから実行することもできます。
本稿では短いプログラムを実行するまでの手順と、基本的なプログラミングについて紹介していきます。言語仕様の詳細はドキュメントのページにある各種の英語版PDFファイルを参照してください。ドキュメントの一部はWikiサイトで閲覧することもできます。
基本的な使い方
ダウンロードとインストール
ダウンロードは、ScalaをインストールするマシンにJDK1.4以上がインストール済みであることを確認してから行います。
ダウンロード用のモジュールは、OSプラットフォームを問わないJavaインストーラや、ZIP、GZIP、RPMなどの形式があります。読者の環境に合ったものを選択してダウンロードしてください。容量はファイルの種類によって異なりますが、約12~17Mバイトあります。
インストールはこれらを展開すれば完了です。必要があれば、展開時に生成されたルートディレクトリ(scala-2.6.0-final、以下%SCALA_HOME%とする)の中にあるbinディレクトリのフルパスを環境変数PATHに追加しておきます。そうすると、Scala関連のコマンドをカレントディレクトリの場所を問わず実行できます。
筆者のWindows環境でZIPをダウンロードし展開したところ、約30Mバイトのフォルダやファイルが生成されました。
コマンドラインシェルでのプログラム実行
Scalaのコマンドラインシェルはscalaコマンドで実行を開始します。終了するには:quitを入力します。コマンドラインシェルの実行から終了までの流れを図1に示します。ここではいわゆるHello Worldプログラムを実行していますが、日本語の文字列もとくに問題なく扱えることがわかります。
classファイルへのコンパイル
ScalaのソースコードをJavaのclassファイルにコンパイルするには、scalacコマンドを実行します。図1で入力していたソースコードをScalaProgramming.scalaとして、それをコンパイル後に実行する例を図2に示します。
Eclipseプラグインのインストール
ScalaにはEclipseプラグインも用意されていますが、こちらはJRE5以上とEclipse SDK 3.3の環境で利用できます。リモートサイトのURLはhttp://www.scala-lang.org/downloads/scala-plugin/ です。プラグインのインストール時にプラグイン開発環境(PDE)が要求されることがありますので、「Europa Discovery Site」から該当するものを探して一緒にインストールしておきましょう(図3)。これは画面右の「Select Required」ボタンをクリックして自動的に選択することもできます。
筆者の環境ではインストール時に警告画面が表示されましたが、「Install」をクリックしたらインストールは無事に完了しました。
Scalaプロジェクトの作成
プラグインのインストールが完了すると、Scalaプロジェクトが作成できるようになります(図4)。そこで、プロジェクトを作成してみましょう。図5で「Scala Project」を選択したら、あとは一般のJavaアプリケーションと同じように操作すれば、Scalaプロジェクトが作成されます(図6)。
EclipseでのScalaアプリケーション開発
さっそくソースコードの入力、といきたいところですが、その前に必ずsrcフォルダのすぐ下にパッケージを作成しておかなくてはなりません。図4のメニューから「Scala Package」を選択してソースコード入力用のパッケージを作成しましょう。
パッケージの作成を終えたら、ここにアプリケーションとなるソースコードを入力するファイルを作成します。リスト1で実行したような、それ自体が起動できるようなものを作成するときは、図4から「Scala Application」を選択します。そしてダイアログにファイル名を入力した後に「Finish」をクリックするとScalaパースペクティブが開き、ソースコードを入力できるようになります。
完成したプログラムを実行した例を図7に示します。Scalaパースペクティブといっても、見た目や操作は一般的なJavaパースペクティブとそれほど違いはありません。ソースコードもハイライトされて読みやすくなっており、筆者の環境では日本語の文字列も特別な設定変更をせずに扱うことができました。
Scalaプログラミングを少しだけ
では、Scalaのプログラミングを少しだけ試してみましょう。Java VM上で動作するとはいっても、Java言語とは異なる部分が多いため、はじめは戸惑ってしまうかもしれませんが、まずはトライしてみることで新しい世界が見えてくるでしょう。
objectとclass
図1を見て、Javaプログラマは不思議に思ったかもしれません。staticを宣言したわけでもないのに、ScalaProgrammingはnewでインスタンスを生成しないままに実行されてしまったからです。
では、ScalaProgrammingインスタンスをnewで生成できるのかといえば、それはできません( 図8)。objectで宣言された場合は、インスタンスを複製しないことを表しているためです。
classで宣言している場合は、newによりインスタンスを生成できます(図9)。objectとは異なり、インスタンスを生成しないと実行できません。両者の違いはJavaプログラマにはちょっと馴染まないところかもしれません。
defはメソッド
defはメソッドを表しますが、メソッドの特殊形として代入文を記述することもできます(ただし代入文用にはvalやvarという予約語があります)。クラスを用いずメソッドだけを実行することが可能です。もちろん再帰処理も記述できます。図10に例を示します。
引数の型は引数の後に、戻り値の型はメソッドの後に、:に続けて記述しますが、戻り値の型は省略可能です。また、returnを記述しない場合は、最後に実行された文の結果がメソッドの戻り値となります。
toとuntil
範囲を表すtoとuntilでは、最後の値が異なります。図11で示すとおり、1 to 5では1から5までの値を表すのに対し、1 until 5では、1から4までの値しか表しません。これらはRubyでいう1..5と1...5にあたります。
Rubyのブロックのような処理ができる
Scalaでは、Rubyでいうブロックのような処理を行うメソッドが用意されています。yieldという、ブロックを実行するメソッドもありますので、Rubyに近いプログラミングが可能です。図12がScalaのメソッド、図13がRubyのブロックの例です。両者でメソッド名や戻り値が異なる場合もありますが、ほぼ同じ処理が実行できることがわかります。
リストや配列ではないタプル
IPアドレスやデータベースのテーブルの1行分のデータのように、複数の要素が集まって1つの集合になっている値というものが存在します。それがタプル(Tuple)です。いったん定義された要素は更新できないというのがリストや配列とは異なる特徴です。PythonやXQueryでもタプルの定義が可能になっています。
タプルの要素は左から_1, _2, ...のように指定します。図14に例を示します。
"""~"""とXML
複数行にわたる長い文字列は"""~"""で記述できます。これはPythonと同じです。そしてXML自体をソースコードに記述できます。これはXQueryと同じです。ソースコード内にこうしたものが記述されているのはJavaプログラマにとっては驚きかもしれませんが、PythonやXQueryの世界ではあたりまえのことなのです。その両方を体験できるScalaは貴重な存在ではないかと思います。
図15に示すとおり、XMLデータが代入された場合は、\や\\を用いて必要なノードのみを抽出することもできます。これはXPathの/や//を真似たものと推測できます。
.や()をつけなくてもよい
Javaプログラミングでは、メソッド名の前には.(ピリオド)がつき、引数を囲むのには()が必要です。しかしScalaでは、図16のように、空白で区切られたものの意味や優先順位が明白であれば、これらを記述しなくても動作する場合があります。
今回紹介できたのはScalaプログラミングのほんの入り口に過ぎません。その先にはJavaでは体験できない世界が遠くまで広がっています。サンプルソースなどを参照しながら、新しい体験をしてみてください。これまで見えていなかったものが見えてくるかもしれません。