2012年12月8日土曜日

eMacsでscaLaを書く準備

この投稿はLL/ML Advent Calendarの12/8向けです。

動機

Scala基礎勉強会にて、Scalaを書くのにemacsを使っている人が多数いたので、
エクなんとかというエディタのことはこの際忘れて、
eMacsでscaLaを書くことに挑戦しようと思い、設定方法などを記事にする次第。


環境

  • CentOS 6.3(64bit)
  • GNU emacs 24.2.2
これらは既に入っている前提で。

で何を入れるの?

scala-mode2

まずは、scala-mode2という、Scala用のメジャーモードを使用します。
scala-mode2は下記の機能を提供してくれます。
  • インデント
  • シンタックスハイライト
  • モーションコマンド
※2012年12月8日現在のステータスとしては、
  • インデント:完成(finalized)
  • ハイライト:仕掛り中
  • モーションコマンド:emacsの標準的なものについては対応していますが、Scalaに特化したものはまだ対応できていない
とのこと。

scala-mode2はGNU emacsの24.2を対象に開発されています。
24より過去にはない機能を使っているそうなのでご注意を。

設定手順

昔はScala本体と一緒に配布されて気もしますが、今はGithubからダウンロードするようです。

ファイルをダウンロードします。
git clone git://github.com/hvesalai/scala-mode2.git

パスなどの情報をemacsの初期化ファイル(自分の場合は~/.emacd.d/init.el)に書き込んでやります。
(add-to-list 'load-path "/path/to/scala-mode2/")
(require 'scala-mode)

基本的にはこれだけです。Emacsを起動して、.scalaファイルを開くと、Scalaモードになっていると思います。


シンタックスハイライトが効いていますね。


ENSIME

が、これだけだとScalaをばりばり書くには物足りません。
やはり補完とかリファクタリングしたいですよねー。
ということでENSIMEを使います。
ENSIMEとは"ENhanced Scala Interaction Mode for Emacs"の略称とのこと。
えんざいむ、と読むそうな。

ENSIMEを導入することにより、
  • ファイルを保存するたびにコンパイルエラーを確認できる
  • 補完
  • 基本的なリファクタリング
  • シンボルのインスペクション
  • パッケージ/型のブラウジング
  • デバッグ(※ステータスはwork in progress)
などができるようになります。

emacsの対象バージョンは22以降。23が推奨されています。
が、私が試している限り、24.2でも問題なく動いています。


設定手順

Downloadサイトから適切なファイルを取得します。

展開後、emacsの初期化ファイルに下記を追記します。
(add-to-list 'load-path "ENSIME_ROOT/elisp/")
(require 'ensime)

(add-hook 'scala-mode-hook 'ensime-scala-mode-hook)

SBTから設定ファイルを作成


ENSIMEを使うには、設定ファイルを作成する必要があります。
設定ファイルを作成する方法は以下の2つの方法が用意されています。
  1. ウィザード形式で対話的に作成する
  2. SBTプロジェクトにて、ENSIMEプラグインを使って生成する
ここでは、2の方法を採用します。
今回は、Play Frameworkで新規作成したプロジェクトについて、ENSIMEの設定ファイルを生成してみます。

※Play Frameworkのバージョンは、2.1-RC1を使います。

{プロジェクトルート}/project/plugins.sbt に下記の通り追記します。

addSbtPlugin("org.ensime" % "ensime-sbt-cmd" % "0.1.0")

その後、プロジェクトルートにて
play
ensime generate

とやるとENSIMEの設定ファイル(.ensime)がプロジェクトルートに作成されます。

ENSIMEの有効化


{プロジェクトルート}/app/controllers/Application.scala をemacsで開いてみます。

右下に[ENSIME: No Connection]というのが見えますね。


M-x ensime

としてやるとENSIMEの機能を有効にできます。


ENSIMEを使った際の画面イメージは?


totoshiさんが
EmacsでつくるScala開発環境 後編(ENSIME)
という分かりやすいポストを書かれているのでご参照ください。



最後に


正直、私のemacs力が低いため、未だemacsでScalaをバリバリ書ける!という状態ではないのですが、
だんだんと慣れていけたらなぁと思います。

明日は@youku_sさんと@kotashanさんが担当です。

2012年12月3日月曜日

Play Frameworkの2.1-SNAPSHOTでDoubleのformatterが追加されていた。

Play Frameworkの2.1-SNAPSHOTでDoubleのformatterが追加されていたのでメモ。

Play Frameworkでの入力フォームについて、2.0以前では、自分でDouble型のフォーマットを書かなくちゃいけなくて面倒でしたが、2.1からはデフォルトでフォーマットが提供されるようです。

2.0の場合も、下記の実装をコピーしてフォーマッターを作れば簡単。

https://github.com/playframework/Play20/blob/master/framework/src/play/src/main/scala/play/api/data/format/Format.scala#L117

 
via http://stackoverflow.com/questions/12759430/play-bind-a-form-field-to-a-double


使い方


2012年7月15日日曜日

ScalaでAndroidのAsyncTaskを使う際に可変長引数でAbstractMethodErrorが発生する件

Androidアプリにて非同期処理を実現しようとするとAsyncTaskを使うわけですが、
Scalaで書こうとすると実行時にAbstractMethodErrorが発生する訳です。
で、これはどうもJava側での可変長引数をScalaでよろしく処理できないためのようで。

てことで検索したら解決策を発見したのでメモ。

https://gist.github.com/1175555

@Override
   protected Result doInBackground(Params... params) {
      return doInBackground(params.length > 0 ? params[0] : null);
   }

   abstract protected Result doInBackground(Params param);


AsyncTaskを継承したJavaクラスを作成し、可変長引数を受け取ったらその1個目の引数を使ってabstractメソッドに処理を移譲しています。

2012年6月7日木曜日

第2回 ドメイン駆動設計読書会@名古屋 のモデル

第2回 ドメイン駆動設計読書会@名古屋 のモデル
http://atnd.org/events/29529


2012年4月25日水曜日

jberkel / android-plugin とEclipse

ScalaでAndroidコードを書きたいなぁ、ということで調べていたら下記のsbtのプラグインがヒットしました。

/ android-plugin

Scala書くときにはEclipseのScala IDEがなかなか使えるし、
Androidのリソースを編集するのにも向いていていいよねー、てことでEclipse用に環境を構築しました。
結果的には、ほとんど下記の方の記事と一緒の設定になりました。

sbteclipse を android-plugin に適用して eclipse で編集する


ちょっと違うのは、私が使ったandroid-pluginが0.6.1だからか、sbteclipse-pluginが2.0.0だからなのか、
Eclipseにインポートした後にしたことは、Build PathのSourceタブにおいて、
  • src/main/res をビルドパスに追加
しただけでした。

逆にしなかったこととしては、
  • src/main/resources、src/test/resources の削除は不要。
  • Librariesタブで、target[scalaバージョン]/classes の追加は不要。
でした。


ひとまず、Eclipse上でエラーが表示されることはなくなりました。

2012年4月15日日曜日

Play Framework 2.0を学ぶ:その2 テンプレートのi18nではまった

Play Framework 2.0(Scala)のテンプレートの国際化ではまったのでメモ。

やりたいこと

テンプレートの文言を外部リソースに切り出したい。
で、言語に対応した文言を表示したい。とりあえず今回は日本語で。


やったこと

Messages and internationalization を参考に、こんな感じで設定。

  1. application.confにて、日本語を使えるように設定。
  2. application.langs="en,ja"
    
    ダブルクオートで囲む必要があるそうな。
  3. conf配下にmessges.jaファイルを作成。
    key=メッセージです!
    
    という形式で登録。
  4. テンプレートを修正し、messagesファイルを参照するよう修正。

    @Mesasges("key")

    という形式で登録。
とここで問題発生。
「メッセージです!」と表示されずに、「key」と表示されてしまいました。

messages.enファイル内でメッセージを定義しても「key」と表示されてしまう始末。

HTTPヘッダーのAccept-Languageにもja、enが含まれているのになー。


解決方法

"play  framework i18n template"で検索したところ、下記を発見。

 i18n error: controller and templates uses different implicit Langs

これによると、
  • Messagesは、implicit paramterとしてLang型の引数(lang)を取る。そのlangは、明示的に指定されない場合、JVMのデフォルトロケールを使う。
  • コントローラ内でMessagesが呼び出される際にimplicit requestが定義してあれば、そのrequestのHTTPヘッダーからAccept-Languageを取得してMessgesの引数langに暗黙的に値を設定してくれる。
  • が、テンプレート内ではスコープ内にlangを見つけられないからJVMデフォルトのロケールが使われるよ。
とのこと。
対応策としては、テンプレートの引数にimplicit parameterとしてLangを付与すれば良い、ということで、viewは下記の通りになります。
(1行目が追加した箇所)


@(implicit lang: Lang)

@Mesasges("key")


こうすると、Messagesの引数に暗黙的にlangの値が渡され、今回の日本語環境の場合はmessages.jaに定義された値を表示します。

2012年2月7日火曜日

Play Framework 2.0を学ぶ:その1 template engine

このあたりを見ながら個人的に重要そうな部分を抜粋。
https://github.com/playframework/Play20/wiki/ScalaTemplates

Play Scalaテンプレート

Play Scalaテンプレートは標準のScalaのfunction(以降、関数)にコンパイルされます。
下記のようなconvention(規約)に基づきます。

views/Application/index.scala.html

というテンプレートファイルを作ると
views.html.Application.index<
という関数を生成します。
上記ファイルの内容が以下のようだとすると

@(customer: Customer, orders: Seq[Order])
 

Welcome @customer.name!

    @orders.map { order =>
  • @order.title
  • }

これはどのScalaコードからでも、下記のように呼び出せます。
val html = views.html.Application.index(customer, orders)

なお、テンプレートファイルの1行目に記載してあるものは、Scala関数の引数とのこと。テンプレートを呼び出す際にも、関数を呼び出すのと同じように、引数に値を渡すんですねー。


"@"キャラクタ

テンプレート上の@は、Scalaコードの始まりと見なされます。
明示的に終了を記述する必要はありません。

ただし、マルチトークン(?)なScalaコードを記述したい場合は、
@(Scalaコード1 + Scalaコード2)のようにかっこでくくる必要があります。

また、{}を使って、複数のステートメントを書くこともできます。

@は特別なキャラクタなので、エスケープする場合は、

@@

と@を重ねる形でエスケープします。


テンプレートパラメータ
テンプレートは単純な関数であるため、パラメータが必要です。
パラメータは、テンプレートファイルの1行目に記述される必要があります。

デフォルト値も使えます。
パラメータグループも使えます。
インプリシットパラメータも使えます。


※その他は今のところ使わなさそうなので省略