かみやんの技術者ブログ

主にプログラムの話です

GoogleのDartを使ってみた

JavaScriptをたくさん使うプロジェクトの現状

JavaScriptをガンガン書かないといけないWebアプリは、ビジネスロジックをJavaServletで書いて(他の言語でもいいけど)、JSPへ転送して(他の言語でもテンプレートとか使うと思うけど)、JavaScriptもクライアントに送って、クライアントでは、HTML+CSSでビジュアルがレイアウトされて、JavaScriptがビジュアルを動かしたり、AJAXでまたサーバにリクエストしたり、AJAXのレスポンスでまたビジュアルが変わったり。例えばレイアウトにバグがあった場合、JavaServletをみたり、JSPをみたり、HTMLやCSSみたり、JavaScriptの実行にエラーがないか確認したり、AJAXで得られたレスポンスの内容をみたりと、かなり開発環境としてカオスであり、不自然な訳です。
あと、JavaScriptのコード量が多くてチーム開発とかだと、コーディングルールをがっちり決めて、ソースコードレビューをしないとめちゃくちゃなコードを書く人が現れたりします。クラス定義の書き方がみんなバラバラだったり、コンストラクタ以外でメンバ変数が勝手に追加されていたり。
//とりあえずここに置いておく
みたいなコメントと共にソースコードの中ほどにメンバ変数が増やされていたりすると、もう死んでくれ!と叫びたくなる訳です。
そもそもJavaScriptのような静的な型がない言語は、IDEの補間が効かなかったり、参照検索がなかったり、実行時にならないと変数名やメソッド名を入力し間違えたことが分からなかったり、名前変更のリファクタリングが効かなかったりと、効率が悪いので好きではありません。
次に作るWebアプリは、JavaScriptに代わる言語で開発したいなと思い、ずっと、代わるものを検討、ウォッチしていました。Dart, Haxe, TypeScript の3つをウォッチしていたのだけど、Haxeは調査済みで一部のプロジェクトで使用し始めています(気が向いたらHaxeのエントリも書きます)。
今回は、GoogleDartを使ってみたのでそのレポート。

Dart言語の特徴

昨年秋に、安定板のDart Editorが出ました。
Dart Editor + Dart SDKは、 http://www.dartlang.org/ ここからダウンロードできます。Dartの特徴は、

  • デスクトップWeb、モバイルWeb、サーバ用と多用途
  • DartVMでも動かせるし、JavaScriptコンパイルしても動かせる
  • 簡素で、効率よく、スケーラブル
  • 分かりやすくて、読みやすい文法
  • Dart言語は、ライブラリもパッケージマネージャもエディタもオープンソース
  • 開発効率を上げるPubパッケージマネージャ
  • DartVMは高速。JavaScriptエンジンのV8の倍速

という感じです。DartVMネイティブで動かせるのは、当面サーバサイドで使うときでしょう。普通は、dart2jsでJavaScriptに変換してWebブラウザの中で使うのが普通でしょう。

主な言語仕様

言語仕様の特徴としては、

  • クラス:prototype baseは色々問題あるよねというところですね
  • クラスの外のトップレベル関数Javaと違ってクラスの外にも関数書けるよと
  • オプション引数:省略可能引数、C++のように引数リストの後ろの方を省略する方法と、名前付き引数にしてどこを省略してもよい2通りがある
  • 文字列インターポレーションPerlのような"Hello, ${name}"みたいな置換ですね
  • マルチライン文字列Perlのヒアドキュメント($s=<<END;)みたいな文字列リテラルですね
  • 動的メソッドハンドリング:実行時にメソッドがあるか確認する(静的にチェックしてほしいのだが)
  • カスケード演算子(..)VBJavaScriptのwithみたいなものですね
  • オプショナルな型:小さなアプリをさっと書くときは型を書かない、ちゃんとしたアプリは、型を書く(私は厳密な型が欲しい)
  • レキシカルスコープ:ちゃんと{}のブロックが識別子のスコープですよ。クロージャも対応しているよ。ローカル変数キャプチャもしているよと。ま、JavaScriptだけが異常だとは思うが。
  • ライブラリ:ライブラリを使うときも作るときも切り替えとかの修正不要。Pubというオープンなリポジトリがかなりお手軽で便利
  • Isolate(アイソレート):マルチスレッドでメモリを共有して管理するのは、開発もデバッグも大変。Isolate同士は、お互いのメモリにアクセスできないので安全

という感じ。ま、モダンな言語仕様ですね。使ってみた感想としては、やはりC++Javaが好きな僕としてはメソッドがあるかどうかを動的に判断するのが辛いか。一応、Dart Editorで黄色い下線がでて警告がでるときもあるけど。
あとは、メソッドのオーバーロードができない。JavaScript風にしたのか、オプショナルな型のせいか、オーバーロードがあるとソースが読みにくいという意図なのか、JavaScriptコンパイルするときに美しくないからか。
あとは、intが初期値を代入していないときは、nullになったり。あたりがちょっと気になったところ。

classの例

// 形状インターフェース
abstract class Shape {// abstractが使える
  num perimeter();// num型は、int型とdouble型のsuperクラス
}

// 矩形クラス
class Rectangle implements Shape {//implementsでShapeインターフェースを実装
  final num height, width; //finalは初期値代入のみ可能で以降変更不可
  Rectangle(this.height, this.width);    // コンパクトコンストラクタ表記。引数でメンバー変数を代入するという意味。
  num perimeter() => 2*height + 2*width; // 関数の省略表記。関数本体が単文のときは、このように省略できる。
}

// 正方形クラス
class Square extends Rectangle {// extendsで矩形を継承(継承は1つまで)
  Square(num size) : super(size, size);//コンストラクタで親クラスのコンストラクタを呼ぶときはC++風にコロンを使う、superという予約語を使うところはJava風。
}

ま、これを見るだけでもモダンな感じですね。

Dart Editorの特徴

IDEであるDart Editorの特徴は、

  • コード補完:メンバ変数やメソッド名が補完される
  • リファクタリング機能:リネームとか
  • アウトラインビュー:クラスのメンバ変数やメソッドがツリー表示
  • デバッガー:ブレイクポイント、変数を見る、ステップ実行
  • 静的解析:メンバ変数じゃないとか、代入してないとか静的解析で警告がでる
  • 呼び出し元検索:呼び出し元検索ですぐにそこを表示できる

という感じ。
使ってみた感想としては、コード補完が効かなくなることがあってDart Editorを再起動したら直ったとか、リファクタリングのリネームは、ライブラリを超えては無理なのか、効かないときがあった。とか、呼び出し元検索は1度も動かなかった。など普段書いているJavaの安心感に比べると心もとない。

作ってみたアプリ


3時間くらいで作ってみたアプリが上記。htmlファイルをほぼ書かず、cssファイルをほぼ書かず、コードでウインドウを作ったり、コントロールを配置したりするWindow Toolkitっぽいもの。クライアント側は、html,cssのコードは書かずにdartだけ書いて、サーバサイドもcssやhtmlはほとんど出力せずにjsonとかだけを出力するシステムをイメージしたもの。
なお、Pubというオープンなリポジトリがありpubコマンドというライブラリマネージャがあり、他の人が作ったライブラリをインストールしたり、アップデートしたり、自分の作ったライブラリをアップロードするのはとても簡単らしいが、pub installコマンドで、自分が書いていたライブラリが削除されるというミスをしてしまいました(そしてオレオレWindow Toolkit作り直し)。pubに関してはまだ調査不足なので、みなさん自分のライブラリを作っている場合は、pubコマンドの使用前にはバックアップしましょう。

#dartをしばらく調査したら、次はTypeScriptを調査予定〜

――
アプリ受託開発、Webシステム受託開発も行っています。以下自社製品。
URL:ibisMail Freeのダウンロード、レビューはこちら
URL:ibisMail for iPhoneのダウンロード、レビューはこちら
URL:ibisMail for iPadのダウンロード、レビューはこちら
URL:ibisPaintのダウンロード、レビューはこちら サイトは、ibispaint.com
ご意見ご要望はTwitterから: @kamiyan