「これは絵文字ですか?」「はい、Unicode6.0です」

携帯向けのWebサービスをやっていく上で、絵文字の対応は頭を悩まされるところです。
最近では、ガラケーことFeaturePhoneに加えSmartPhoneも多く普及してきました。
そこで、現在の絵文字事情がどうなっているかを調べてみました。

現在の絵文字の状況

日本では、docomo, au, SoftBankの3キャリアごとにそれぞれ違った文字コードの絵文字が存在します。
世界に目を向けると、GoogleとAppleが主体となって絵文字の標準化を行なっており、
2010年10月にUnicode6.0で絵文字の国際標準が策定されました。
そのため、現在のスマートフォンを取り巻く絵文字事情は、docomo, au, SoftBank3キャリアの群雄割拠にUnicode6.0も参戦する太陽曰く(」・ω・)」うー!(/・ω・)/にゃーな状況となっています。
最近では、iOSが5.1になって他キャリアに絵文字が送れなくなったなんてことも発生していました。

なお、Unicode6.0で採用された文字コード体系は、Googleのemoji4unicodeがベースになっています。

絵文字の対応方法

通常Webサービスなどで絵文字を保存する場合は、

  • いずれかのキャリアの文字コードに変換
  • 独自の形式に変換

のどちらかを行ない、内部では1種類の絵文字コードで保存を行います。
日本ではdocomoユーザーが最も多いため、docomoの絵文字コードに統一して保存を行う場合が多いようです。
ちなみに、弊社の提供しているおみせやさんでは内部ではGoogle emoji4unicodeの下位16bitの文字コードに変換して保存をしています。(下位16bitはPUAなのでまず問題は起きません。詳しい説明は後述)

絵文字の変換フロー

各機種絵文字対応状況

現在の、スマートフォンの絵文字対応状況を紹介しておきます。
iPhoneのみが特殊で、OSのバージョンによって送信時の文字コードが違う+表示はUnicode6.0とSoftBank共に出来る状態になっています。
表示確認は周りにおちてた機種のみでしかしていませんのであしからず。

機種 OS キャリア 入力時の文字コード 表示できる文字コード
iPhone4 iOS 4.X SoftBank SoftBank Unicode6.0,SoftBank
iOS 5.X SoftBank Unicode6.0 Unicode6.0,SoftBank
iPhone4S iOS 5.X SoftBank Unicode6.0 Unicode6.0,SoftBank
Sumsong Galaxy S2 LTE Android 2.3 docomo Google docomo,Google
NEC Medias N06c Android 2.3 docomo Google Google
Sharp Galapagos Android 2.3 SoftBank Google SoftBank,Google
Sharp IS03 Android 2.2 au Google Google

- 5/16 19:00 機種を追加+間違っていた情報を修正

スマートフォン時代の絵文字の取り扱い方は?

既存のサービスを持っているところは現状維持が妥当とは思いますが、これから新規にサービスを立ち上げようとする場合はどのようにするのが良いでしょうか?

方法は、

  • Unicode6.0標準をそのまま使用する
  • Unicode6.0標準の下位16bitを使う

のどちらかかと思います。なるべくなら、前者をおすすめします。

理由その1 すべての絵文字を網羅している

3キャリアの絵文字では相互に変換できない絵文字が存在するため、どうしても特定のキャリアで使えない絵文字が出来てしまいます。
Unicode6.0であれば、3キャリアの絵文字 => Unicode6.0への変換はもれなく行うことができます。
またUnicode6.0 => 3キャリアの絵文字へは変換できない場合もありますが、絵文字の名前が定義されているので絵文字の変わりにその名前を表示することも可能です。

理由その2 今後標準になっていく

iOSはUnicode6.0での表示にすでに対応しています。MacでもUnicode6.0ならばそのまま絵文字が表示可能になっています。
WindowsPhoneも同様に徐々に対応してきているそうです。(実機では未確認。wikiから)
また、現在Androidは対応していませんがGoogleが標準化の主要メンバーであるので今後対応していってくれると思います。
なのでUnicode6.0にしておくと、将来的にキャリア別に絵文字の文字コードを変換をしなくても良くなる可能性が高いです。

ただし・・・

Unicode6.0の絵文字はU+1F200 ~ U+1F700台に多くがマップされています。これらのUnicodeはUTF-8でエンコードした場合4byte長になってしまいます。
現時点では、4byte長のUTF-8をうまく扱えないor扱うのが面倒なシステムが多く存在します。
例えば弊社ではMySQLを利用していますが、MySQLのUTF-8は4Byte長の文字を扱えません。MySQL5.5からは「utf8mb4」というCharacterSetが導入されたので4byte長も扱えるようになっていますが、それ以前のバージョンではBLOBを使ってバイナリとして保存をするしか方法がありませんでした。
また、最近はやりのNode.jsも、ベースになってるV8エンジンが4byte長UTF-8を扱えないため、文字列ではなくバイナリデータとして取り扱う必要があります。

このような事情から、現時点ではシステムによっては絵文字が含まれうる文字列は、バイナリデータとして無理やり使う必要があります。しかし、バイナリデータとしてしまうと、ライブラリ等に用意されている文字列関数が使えなくなってしまい取り扱いが面倒になることがあります。
そこで、下位の16bit分だけを利用するというのもひとつの解決策になります。下位16bitはU+F200 ~ U+F700台になり、これはUnicodeのPrivate Use Areaであるので、通常では他の文字とかぶっていません。そのため、下位16bitのみを使用しても問題になることはありません。ただし、入力時や表示時に変換が必須となるのでそのへんの手間を考えて、そのまま使うか下位16bitのみを使うかを決めたほうがいいと思います。

参考にしたサイト

MySQLで4バイトのUTF-8文字を扱ってみる
絵文字のUnicode6.0と各キャリアの対応表

Posted in iOS | Tagged , , | Leave a comment

Flash変換ライブラリ「Lightning」を公開しました

芸者東京の山内です。
弊社にて開発したPythonベースFlash変換ライブラリ「Lightning」をオープンソースで公開しました。
lightning (github)
ライセンスはThe MIT Licenseです。

このライブラリは弊社アプリ「おみせやさん」のiPhone版で店やアバターを表現するのに使っています。
Flashで作成したswfファイルを、LightningによってiPhone用のWeb素材に変換します。

Lightningのすごい所

1. 高い再現率
SVGによるベクターグラフィックスと、CSS3-keyframeAnimationを組み合わせて利用し、再現率の高いアニメーションを実現しています。
swfとほぼ同等の見た目が再現できます。

2. 滑らかなアニメーション
例えば弊社アプリ「おみせやさん」の素材の内部パーツ点数は80-140程度でとても多く、既存のswf変換ライブラリはコマ落ちが発生してしまうのですが、LightningですとiPhone3GSの性能でも十分な速度でアニメーションを再生できます。
「おみせやさん」の10000種類ほどある素材に関してはアニメーション速度が遅れたり、コマ落ちしたりという現象は発生していません。

3. 高速な動作
iPhoneではcanvasを使った描画の場合、CPUの速度の関係で最新の機種でも15fps程度が限界となってしまいます。
しかし、Lightningによって生成されたアニメーションはGPUを使うように調整されているため、24fpsやそれ以上の滑らかなアニメーション表示が可能になります。
また、iPhoneへのデータは静的なSVG, CSSとして渡されているため、ほかのjavascriptを中心としたライブラリと違い、データ取得完了から描画開始までの待ち時間がありません。

 


 

Lightningの使い方

LightningはLinux環境での動作を想定しています。
Python>=2.5,<3.0がすでにインストールされているものとします。
以下の手順にしたがってリポジトリに入っているサンプルファイルを変換してみましょう。

1. lightningのダウンロード
githubからcloneします。
git clone git://github.com/geishatokyo-lightning/lightning.git

2. lightningのインストール
cd lightning && python setup.py install

3. サンプル実行

cd lightning_core/sample && python xml2html.py sample1.xml sample1.html

同梱してあるサンプルファイルを変換します。sample1.html が生成されます。

iPhoneをターゲットとしているため、SafariまたはChromeでご確認ください。

 


 

Demo

SWFとlightningを並べてみました。
SafariかChromeで見てください。
Firefoxだと下記のサンプルが正常に表示されないようです(WordPressのinline htmlの問題っぽい)

SWF


Lightning

使用上の注意
Lightningでは、swfmillによってswf素材をxmlに変換する必要があります。
http://swfmill.org/ から swfmill をダウンロードしてインストールしましょう。(Linuxだけでなく、WindowsやMacにも対応しています。)
以下のコマンドでswfをswfmillでxmlに変換できます。
swfmill swf2xml sample.swf sample.xml

Posted in Lightning, Python | Leave a comment

今流行のArctic.jsと、enchant.jsの比較

こんにちは

ライセンス云々で話題になっていたArctic.jsですが、スマフォに特化したCanvas Frameworkということで
機能的にどうなのか、というところが大変気になります。弊社では同じゲーム向けのJSFrameworkとして、
enchant.jsを使用しているので機能をざっくり比較してみようと思います。

機能の差

Arctic.js enchant.js
サイズ(byte) 90851 88593
圧縮後サイズ(byte) 36696 33570
オブジェクトの描画 canvas上 div毎
License MIT MIT or GPLv3

圧縮後のファイルサイズはenchant.jsのほうが3kbほど少ないですね。
どちらもjs上に継承などを行う擬似クラスを作るためのClass要素があったり、スマートフォン/PC両方で使えるようにtouch系イベントとmouseDown/Move系イベントを判定したり、fps(フレーム数)を設定してフレーム毎のイベントを設定するなどしています。

Arctic.jsだけにある機能としては、Ajax対応(ただしJSONPはサポートしていないので、すべて同ドメインのサーバで処理する必要がある)、FLASHライクなタイムライン指定でのアニメーション機能があります。
反対に、enchant.jsだけにある機能としてはaudio要素への対応としてのSoundオブジェクト、RPGのフィールドマップのようなものを作るMapオブジェクト、あとはプロパティ型の記述ができるのが特徴でしょうか。

label.text = 'abc'; img.x=12; と書くenchant.jsのほうが、
labe.setText('abc'); img.setX(12); とするArctic.jsよりも直感的ですよね。

後発だけあって、Arctic.jsのほうはenchant.jsの機能をパクったenchant.jsにある基本的な機能はだいたいあるような感じですね。

オブジェクトの描画についてですが、Canvasでの描画の方が性能的に有利かもしれませんが、enchant.jsは
divタグ毎にオブジェクトに持っていることで利便性をあげています。既存のアニメーション効果をdivタグ単位で
適応することにより、今までのエフェクトを使いまわすことができるのです。

enchant.jsと他のライブラリを合わせて使うサンプルはこちらのブログに具体的な実装方法が書かれていたので、実装方法はリンク先を御覧ください。

スプライトするまでのコードの比較

Arctic.js

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Test Sprite</title>
	<script type="text/javascript" src="./arctic.js"></script>
	<script type="text/javascript">
        var GameMain = arc.Class.create(arc.Game, {
            initialize:function(params) {
                var sp = new arc.display.Sprite(this._system.getImage('a.png'));
                sp.setX(10);
                sp.setY(10);
                this.addChild(sp);
            },
            update:function() {
            }
        });
        window.addEventListener('DOMContentLoaded', function(e){
            var system = new arc.System(320, 416, 'test');
            system.setGameClass(GameMain);
            system.load(['a.png']);
        }, false);
        </script>
</head>
<body>
<canvas id='test'></canvas>
</body>
</html>

enchant.js

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <script type="text/javascript" src="./enchant.js"></script>
    <script type="text/javascript">
        enchant();
        window.onload = function() {
            var game = new Game(416,320);
            game.preload('a.png');
            game.onload = function() {
                var test = new Sprite(100,100);
                test.x = 10;
                test.y = 10;
                test.image = game.assets['a.png'];
                game.rootScene.addChild(test);
            };
            game.start();
        };
    </script>
</head>
<body>
</body>
</html>

どちらもオブジェクト指向的に書くようですが、enchant.jsの方がすっきり書けるようです。

ちなみにenchant.jsでもcanvasの描画機能が強化されるようです。
αブレンドもそのうちサポートされるとか。(詳細はこちら)

ぼちぼちスプライトの性能の差も比較していこうと思います。
それはまた別記事でっ!

追記:
無理にArctic.jsでスッキリ書くと、こんな感じでしょうか。

Arctic.js

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Test Sprite</title>
	<script type="text/javascript" src="./arctic.js"></script>
	<script type="text/javascript">
        window.onload = function(){
            var system = new arc.System(320, 416, 'test');
            system.setGameClass(arc.Class.create(arc.Game, {
				initialize:function(params) {
					var sp = new arc.display.Sprite(this._system.getImage('a.png'));
					sp.setX(10);
					sp.setY(10);
					this.addChild(sp);
				}
			}));
            system.load(['a.png']);
        }
        </script>
</head>
<body>
<canvas id='test'></canvas>
</body>
</html>

・・・ネスト多い。

Posted in Android, JavaScript, iOS | 1 Comment

MavenからSBTへのビルド環境の移行 依存関係解決

目次へ戻る

この項目ではおもに依存関係の解決方法の説明をします。
sbtは内部でApache Ivyを使用しています。
MavenCentralやScala-toolsなどのMavenRepositoryは問題なく使えますが、ローカルのMavenとの連携は多少設定が必要となります。

1. 依存関係の設定

依存関係は、libraryDependenciesのSettingKeyに設定することになります。
libraryDependenciesの受け取る型はSeq[ModuleID]となっており、依存するライブラリを全て列挙することとなります。

javaのライブラリの場合

mavenでは

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.1</version>
</dependency>

sbtでは

libraryDependencies += "com.google.code.gson" % "gson" % "2.1" % "compile"

のように書きます。
まず、演算子が := では無く、 +=になっていることに注意してください。
:= は代入となり、値を全て上書きしてしまいます。+=は新しい要素の追加になります。
ModuleIDはimplicit conversionによって変換されています。演算子には%を使います。書式は

"groupID" % "artifactID" % "version" [% "scope"]

です。scopeには、”compile”,”test”,”provided”が使用可能です。またscopeは省略可能で、デフォルトでは”compile”とみなされます。

scalaライブラリの場合

scalaのライブラリは慣習的にartifactIDの末尾にscalaのバージョンが付与されます。

<dependency>
    <groupId>org.scalatest</groupId>
    <artifactId>scalatest_2.9.1</artifactId>
    <version>1.7.RC1</version>
</dependency>

このようなscalaライブラリの場合、sbtでは

libraryDependencies += "org.scalatest" %% "scalatest" % "1.7.RC1"

と設定します。注意する点は、groupIDのあとの演算子が % -> %%になっており、artifactIDにscalaVersionをくっつけていないという点です。
このように記述することで、sbtが依存関係の解決を行う際に自動でartifactIDに現在設定しているscalaのバージョンを付与してくれます。

2. 外部Repositoryの設定

デフォルトでMavenCentralRepositoryやScalaToolsが設定されています。
が場合によっては社内Repositoryや野良Repositoryを使いたくなる場合があると思います。
このようなRepositoryの設定はresolversのSettingKeyに追加します
設定方法

resolvers ++= Seq(
  "Company Repos" at "http://hoge.nexus.com",
  "Another Company Repos" at "http://another.company.com"
)

今回は複数のRepositoryを一括で登録して見ました。
代入演算子++=はSeq同士を結合する演算子になります。resolversはSeq[Resolver]なのでこの演算子が使用可能です。
また、今回もimplicit conversionが使用されておりReslverを明示的にインスタンス化する必要はありません。

3. MavenLocalRepositoryの設定

Mavenを使っている人はmvn installでローカルにいろいろなライブラリをインストールしている思います。
しかし、sbtはIvyを使用しているので、デフォルトではMavenのローカルレポジトリを参照してくれません。
でも安心して下さい。sbtには簡単にMavenLocalRepositoryを追加する手段が用意されています。

resolvers += Resolver.mavenLocal

を書き加えるだけでMavenLocalRepositoryの設定は完了します。

4. settings.xmlの置き換え

Mavenを使っているなら社内レポジトリなどの共通設定は当然settings.xmlに全て設定して無駄な手間をなくしていると思います。
sbtを使っていても同じ事を思いますよね?sbtにもsettings.xmlのようにグローバルな設定を記述する方法が用意されています。

ユーザーのホームディレクトリの下に.sbtディレクトリを作り、その中にglobal.sbtファイルを作成してください。

windows
C:\Users\{user name}\.sbt\global.sbt
Linuxなど
~/.sbt/global.sbt

global.sbt

resolvers += "Company Repository" at "http://mycompany.nexus.com/maven/snapshot/"

credentials += Credentials("Sonatype Nexus Repository Manager", "mycompany.nexus.com", {user name}, {password})

設定の方法はBuild.scalaとほぼ一緒です。ただし、Build.sbtと同様な簡易記法になります。そのため、クラスの定義は不要で、SettingKeyとValueだけを列挙すれば大丈夫です。
注意点は、1設定ごと1行開けないと正しく動きません。

credentialsは、認証の設定です。APIによると

Credencial.apply(realm : String,host : String, userName : String, password : String)

となっています。認証のかかっているサーバーごとに正しく設定しましょう。

現在のBuild.scalaはこのようになっています。
依存関係は、いくつも列挙することになると思うので別途定義しておいたほうが綺麗になります。

import sbt._
import Keys._

object HelloBuild extends Build {

  val gson = "com.google.code.gson" % "gson" % "2.1"
  val scalaTest = "org.scalatest" %% "scalatest" % "1.7.RC1" % "test"
  lazy val dependencies = Seq(
    gson,
    scalaTest
  )

  lazy val root = Project(id = "sbt-gson",
    base =  file("."),
    settings = Project.defaultSettings ++ Seq(
      version := "0.0.1-SNAPSHOT",
      organization := "com.geishatokyo",
      description := "this is gson program",
      scalaVersion := "2.9.1",
      crossScalaVersions := Seq("2.9.0-1","2.9.0"),
      libraryDependencies ++= dependencies,
      resolvers += Resolver.mavenLocal
    )
  )
}

目次へ | デプロイへ(準備中)

Posted in Scala, maven, sbt | 2 Comments

MavenからSBTへのビルド環境の移行 プロジェクトの準備

目次へ戻る

1. SBTプロジェクトファイルの準備

今回は、JSONライブラリのGSONを使ってJSONのパースをするプログラムとそのテストを作りたいと思います。
まず、適当に空のディレクトリを作成しそこへ移動してください。

1.1 sbtプロジェクトファイルの用意

projectディレクトリを作成し、Build.scalaというファイルを作成し以下のコードを書いてください。

import sbt._
import Keys._

object HelloBuild extends Build {
  lazy val root = Project(id = "hello",
    base =  file("."),
    settings = Project.defaultSettings ++ Seq(
      version := "0.0.1-SNAPSHOT"
    )
  )

}

あとは、sbtを実行(すでに実行している場合は、reloadで再読み込み)を行なってエラーが起きないことを確認してください。
これが、最小構成のsbtのプロジェクトファイルになります。
sbtの思想を簡単に説明しておくと、sbtでは全ての設定がSettingKeyとValueのペアとなっています。この例では、

version := "0.0.1-SNAPSHOT"

の部分が設定に相当し、versionというSettingKeyに”0.0.1-SNAPSHOT”というValueを設定しています。その他の設定もこのようにKeyValueのペアとして表現されます。

2. 基本設定

2.1 groupIdやartifactId等の設定

mavenのgroupIdやartifactIdなどの基本情報の設定は以下のように対応します。
これ以外の使用可能なSettingKeyはsbt.Keysに定義されています。

Mavenでのタグ名 SettingKey
groupId organization
artifactId Project@id + “_” + scalaVersion
version version
description description
import sbt._
import Keys._

object HelloBuild extends Build {
  lazy val root = Project(id = "sbt-gson",
    base =  file("."),
    settings = Project.defaultSettings ++ Seq(
      version := "0.0.1-SNAPSHOT",
      organization := "com.geishatokyo",
      description := "this is gson program"
    )
  )
}

はpomファイルの

<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.geishatokyo</groupId>
    <artifactId>sbt-gson_2.9.1</artifactId>
    <packaging>jar</packaging>
    <description>this is gson program</description>
    <version>0.0.1-SNAPSHOT</version>
    <name>sbt-gson</name>
    ...
</project>

と等価になります。なお、sbtコンソールで

make-pom

コマンドを使用するとpomファイルを生成してくれます。

2.2 scala version

sbtではコンパイルに使用するscalaのバージョンと、CrossVersionBuildの設定が簡単に行えます。
現在はデフォルトではscala2.9.1が使用されます。

SettingKeyは

scalaVersion String scalaVersion := “2.9.1″
crossScalaVersions Seq[String] crossScalaVersion := Seq(“2.7.7″,”2.8.1″,”2.9.0″,”2.9.0-1″,”2.9.1″)

crossScalaVersionsを設定しておくと、

+compile
+publish

と+を付けてコマンド実行すると設定したscala version全てでビルドや配置を行なってくれます。

今回はscala2.9.1とscala2.9.0でコンパイルします。
最終的なBuild.scalaは以下のようになります。

import sbt._
import Keys._

object HelloBuild extends Build {
  lazy val root = Project(id = "sbt-gson",
    base =  file("."),
    settings = Project.defaultSettings ++ Seq(
      version := "0.0.1-SNAPSHOT",
      organization := "com.geishatokyo",
      description := "this is gson program",
      scalaVersion := "2.9.1",
      crossScalaVersions := Seq("2.9.0-1","2.9.0")
    )
  )
}

目次へ | 依存関係解決へ

Posted in Scala, maven, sbt | Tagged , , | Leave a comment

MavenからSBTへのビルド環境の移行 SBTのセットアップ

目次へ戻る

1. SBTのインストール

sbtはこちらから取得できます。

1.1 Windows

まず、Setupのinstalling sbtのところからsbt-launch.jarをダウンロードして適当なフォルダに置いてください。
次にjarを保存したディレクトリに以下の内容を書いたsbt.batを作ります。

set SCRIPT_DIR=%~dp0
java -Xmx512M -jar "%SCRIPT_DIR%sbt-launch.jar" %*

最後に、コントロールパネルの環境変数でPathにこのsbt.batとsbt-launch.jarをおいたディレクトリを通してください。
以上でSBTを使う準備は完了です。

LinuxとかMacとか

だいたい手順は一緒です。書くのがめんどくさいので本家Wikiを参照してください。

2. Hello SBT

2.1 起動

sbtを使うだけならば、コマンドプロンプトから適当なディレクトリで

sbt

とだけ入力してください。SBTの対話モードが起動します。

2.2 ソースコード

sbtのプロジェクトのディレクトリ構成は以下のようになります。

src/
  main/
    resources/
       <リソースファイル>
    scala/
       <scalaソースコード>
    java/
       <javaソースコード>
  test/
    resources
       <テストリソース>
    scala/
       <scalaテストコード>
    java/
       <javaテストコード>
project
       <sbtプロジェクトファイル>
target
       <コンパイルされたクラスファイルなどsbtが自動生成したファイルの出力先>

Mavenとソースコードのディレクトリ構成は同じです。

src/main/scalaに以下のようなhellosbt.scalaを入れておいてください。

object App{
  def main(args : Array[String]) {
    println("hello sbt!")
  }
}

2.3 コンパイルと実行

実行は次の手順で行えます。

> sbt
sbt> reload
 ...
sbt> update
  ...
  [success] ...
sbt> compile
  [success] ...
sbt> run
hello sbt!

これでさきほどのScalaプログラムが実行できました。簡単ですね。

3. SBTの概要

3.1 よく使うSBTコンソールコマンドの説明

先ほどHelloWorldで使用した4つのコマンドに加えて、よく使うコマンド5つを簡単に説明しておきます。とりあえずこれだけ覚えとけばsbtは使えます。

reload

sbtのプロジェクトファイルを再読み込みします。sbtはプロジェクトファイルの変更を監視していないので、依存関係の追加などの設定変更を行った場合、sbt自体を再起動するか、reloadコマンドを実行してやる再読み込みを行う必要があります。(今さっきのHello sbtではこのコマンドは不要でした。)

update

設定した依存関係を解決し、jarファイルをローカルのIvyレポジトリへダウンロードしてきます。依存関係に変更がない限り、1度だけ実行すれば大丈夫です。(これも先ほどのHello sbtでは不要でした)

compile

コンパイルをします。

test

src/test/以下のテストを実行します。

run

自動でmain関数を探して実行します。

console

依存関係のjarを全てパスに通した状態でscalaのREPLを起動します。

publish

プロジェクトのプログラムを、ローカルレポジトリや外部のレポジトリへ配置します。

clean

target内のファイルを削除し、まっさらな状態にリセットします。全てのソースを再コンパイルしたい場合などに使用します。

tasks

現在のsbt projectで使用可能なコマンドの一覧が表示されます。他の機能は暇な時にこれで表示させてみてください。

Mavenの違いとしては、mvn compileやmvn testでは自動で依存関係の更新まで行なってくれますが、sbtでは依存関係の更新は明示的にupdateを実行する必要があります。(そのかわり、testやcompileのときにいちいち依存関係に解決を行わないので早い)
あとは、sbtには簡単にコードを実行できるrunとconsoleコマンドがあります。とくにconsoleのほうは、ライブラリを試しに使って見るときに非常に重宝します。

3.2 pom.xmlに変わるもの

sbtでは、

  • Build.sbtによる、KeyValue型簡易設定方式
  • projectディレクトリに*.scalaを記述する詳細設定方式

の2種類のプロジェクト設定方法が用意されています。
今回は、後者の詳細設定方式を使いたいと思います。

Posted in Scala, maven, sbt | 1 Comment

MavenからSBTへのビルド環境の移行

この記事は、sbt0.11.X系列の記事です。それ以前のバージョンでは正しく動作しません。

SBTとは

Scala(とついでにJava)のためのビルドツールです。ちなみにSimple Build Toolの略です。
特徴としては、設定等全てscalaで書くことができ拡張性が高いビルドツールになっています。

この記事では、Mavenの主要な機能を順次sbtへと移植していきます。
現在ScalaをMavenと連携して使用しているけど、sbtも安定してきた気がするしsbtへ乗り換えてみようかなと思っている人達を対象にしています。
sbtに関しては、使う上での最低限の情報と、Mavenからの移植に必要な部分のみ触れています。
きちんとsbtの使い方を知りたい方は、本家のWikiを読んでください。

目次

SBTのセットアップ

プロジェクトの準備

依存関係解決

デプロイ

Comming soon?

Posted in Scala, maven, sbt | 1 Comment

CSSのベンダープリフィックスを自動で追加するテクニックまとめ

こんにちわ!GTEエンジニアの小橋です。

みなさん、CSS3してますか?CSS3によって表現は大幅に広がりましたが、一方で対応状況はブラウザによって様々…。
CSSでベンダープリフィックス(-mozとか、-webkitとか…)を複数記述するのはめんどくさいですよね?
というわけで、何とかしてくれる手法をまとめてみました。

Prefixr

Prefixr : http://prefixr.com/index.php
入力したCSSに、ベンダープリフィックスを付与してくれるWebサービスです。
こういうCSSを記述すると…

#test {
	border:5px #222 solid;
	border-radius:10px;
	transform:skew(5deg,5deg);
	background: linear-gradient(top,  #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);
	}

こんな形に変換してくれます!

#test {
	border: 5px #222 solid;

	-webkit-border-radius: 10px;
	-moz-border-radius: 10px;
	border-radius: 10px;

	-webkit-transform: skew(5deg,5deg);
	-moz-transform: skew(5deg,5deg);
	-o-transform: skew(5deg,5deg);
	-ms-transform: skew(5deg,5deg);
	transform: skew(5deg,5deg);

	background: -webkit-linear-gradient(top, #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);
	background: -moz-linear-gradient(top, #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);
	background: -o-linear-gradient(top, #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);
	background: -ms-linear-gradient(top, #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);
	background: linear-gradient(top, #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);
}

また、Prefixrにはcssをワンライナーに圧縮する機能もついています。(”Compress My Code”のチェックを入れるだけ)
Webサービスでココまでやってくれるのは嬉しいですね。

vim用のプラグインも有るみたいなので、『CSSはvimで書く!』という人には良いですね。

-prefix-my css

-prefix-my css : http://prefixmycss.com/
Prefixrと同じような感じの、ウェブサービス型。

#test{
border:5px #222 solid;
/*border-radius*/
-webkit-border-radius:10px;
   -moz-border-radius:10px;
        border-radius:10px;
/*transform*/
-webkit-transform:skew(5deg,5deg);
   -moz-transform:skew(5deg,5deg);
    -ms-transform:skew(5deg,5deg);
     -o-transform:skew(5deg,5deg);
        transform:skew(5deg,5deg);
/*linear-gradient*/
background:-webkit-gradient(linear,left top,left bottom,color-stop(#e1ffff,0),color-stop(#e1ffff,0.07),color-stop(#e1ffff,0.12),color-stop(#fdffff,0.12),color-stop(#e6f8fd,0.3),color-stop(#c8eefb,0.54),color-stop(#bee4f8,0.75),color-stop(#b1d8f5,1));
background:-webkit-linear-gradient(top,  #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);
background:   -moz-linear-gradient(top,  #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);
background:     -o-linear-gradient(top,  #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);
background:        linear-gradient(top,  #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);
}

インデント付けてくれるのでPrefixrと比べて見やすい方をお好みで、でしょうか。
※ background:-webkit-gradient の変換などに差異があり、-webkit-gradientのものはうまく動かないですね。

-prefix-free

-prefix-free : http://leaverou.github.com/prefixfree/
javascriptベースでCSSを書き換えてくれます。

<script src="prefixfree.js"></script>

このようにjsファイルを読み込むだけで、<style>~</style>で書いたcssや<link rel=”stylesheet” type=”text/css” />で読み込んだcss、DOMエレメントのstyle要素に記述したcssはもちろん、javascript経由で設定するcssまで適用してくれます!
ファイルサイズは5KBと軽量なうえ、jQuery等のライブラリに依存することもありません。

なによりすごいのは、javascript経由で設定したstyleまでベンダープリフィックスをつけた形で適用してくれること。
・・・もっとも、この機能はchromeとoperaで正常に動作しないそうです。
そのため、-prefix-free の jQueryプラグインを導入して、 $('#obj').css('transform', 'rotate(30deg)') などとするほうが良いようですね。

compass

compass: http://compass-style.org/
これがベンダープリフィックス追加も含めた本命になると思います。

Rubyベースの、CSS構築フレームワークです。『CSSを生成するためのメタ記述が可能な言語』というところでしょうか。
同じシンプルな記述からCSSを生成することで有名なSassの拡張として作られています。
.scssというファイルに記述したCSSっぽい内容のものを、変換(コンパイル)して使います。
導入は、Rubyが導入されていれば簡単です。(winの人は適当に導入しておきましょう)


$ gem update --system
$ gem install compass

たったこれだけで導入完了!

■はじめて使う


## 基本ファイル作成
$ compass create
## 変更監視して、自動コンパイル
$ compass watch

■Railsプロジェクトに導入


$ rails new 
$ compass init rails 

先ほどと同じCSSを変換してみましょう。
compass create を実行して出来たファイル /sass/screen.scss を編集します。
記述がちょっと違うので注意が必要ですね。

@import "compass/css3/";
#test {
	border:5px #222 solid;
	@include border-radius(10px); /* 記述がだいぶ違うので注意です */
	@include skew(5deg,5deg); /* "transform"が不要です */
	@include background(linear-gradient(top,  #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%));
	}

編集が終わったら、 compass compile です。

@charset "Windows-31J";
/* line 3, ../sass/screen.scss */
#test {
  border: 5px #222 solid;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  -o-border-radius: 10px;
  -ms-border-radius: 10px;
  -khtml-border-radius: 10px;
  border-radius: 10px;
  /* 記述がだいぶ違うので注意です */
  -moz-transform: skew(5deg, 5deg);
  -webkit-transform: skew(5deg, 5deg);
  -o-transform: skew(5deg, 5deg);
  -ms-transform: skew(5deg, 5deg);
  transform: skew(5deg, 5deg);
  /* "transform"が不要です */
  background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #e1ffff), color-stop(7%, #e1ffff), color-stop(12%, #e1ffff), color-stop(12%, #fdffff), color-stop(30%, #e6f8fd), color-stop(54%, #c8eefb), color-stop(75%, #bee4f8), color-stop(100%, #b1d8f5));
  background: -webkit-linear-gradient(top, #e1ffff 0%, #e1ffff 7%, #e1ffff 12%, #fdffff 12%, #e6f8fd 30%, #c8eefb 54%, #bee4f8 75%, #b1d8f5 100%);
  background: -moz-linear-gradient(top, #e1ffff 0%, #e1ffff 7%, #e1ffff 12%, #fdffff 12%, #e6f8fd 30%, #c8eefb 54%, #bee4f8 75%, #b1d8f5 100%);
  background: -o-linear-gradient(top, #e1ffff 0%, #e1ffff 7%, #e1ffff 12%, #fdffff 12%, #e6f8fd 30%, #c8eefb 54%, #bee4f8 75%, #b1d8f5 100%);
  background: -ms-linear-gradient(top, #e1ffff 0%, #e1ffff 7%, #e1ffff 12%, #fdffff 12%, #e6f8fd 30%, #c8eefb 54%, #bee4f8 75%, #b1d8f5 100%);
  background: linear-gradient(top, #e1ffff 0%, #e1ffff 7%, #e1ffff 12%, #fdffff 12%, #e6f8fd 30%, #c8eefb 54%, #bee4f8 75%, #b1d8f5 100%);
}

出力結果もだいぶ違いますね!
普通にコンパイルすると、このcssは、.scssファイルの何行目か…という情報がコメントとしてついてきます。

なお、圧縮コンパイルするには compass compile -s compressed sass/* を使います。

#test{border:5px #222 solid;-moz-border-radius:10px;-webkit-border-radius:10px;-o-border-radius:10px;-ms-border-radius:10px;-khtml-border-radius:10px;border-radius:10px;-moz-transform:skew(5deg, 5deg);-webkit-transform:skew(5deg, 5deg);-o-transform:skew(5deg, 5deg);-ms-transform:skew(5deg, 5deg);transform:skew(5deg, 5deg);background:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #e1ffff), color-stop(7%, #e1ffff), color-stop(12%, #e1ffff), color-stop(12%, #fdffff), color-stop(30%, #e6f8fd), color-stop(54%, #c8eefb), color-stop(75%, #bee4f8), color-stop(100%, #b1d8f5));background:-webkit-linear-gradient(top, #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);background:-moz-linear-gradient(top, #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);background:-o-linear-gradient(top, #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);background:-ms-linear-gradient(top, #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%);background:linear-gradient(top, #e1ffff 0%,#e1ffff 7%,#e1ffff 12%,#fdffff 12%,#e6f8fd 30%,#c8eefb 54%,#bee4f8 75%,#b1d8f5 100%)}

compassには、css3のレイアウトフレームワーク:Blueprintが使えたり、変数などを使ってcssを記述できるscss記法が使えたりと色々高機能ですね!
compass watch を使えば、毎回コンパイルする必要なくファイル変更時に自動コンパイルしてくれるのも、開発効率が上がりそうで良い感じです。

また、コマンドラインが面倒くさい!という人のために、アプリ版がオススメ。
http://mhs.github.com/scout-app/
こちらはwin版/Mac版があり、Ruby実行環境も不要!
デザイナーさん向けにはこちらが良いかもしれませんね。

Posted in JavaScript, css | Leave a comment

Play frameworkで動的にリンクを作る(for scala)

こんにちは。GTEエソヅニアの岡谷です。

クリスマスはPlay framework(Ver1.2.4)とアツい夜を過ごしたので、その時得た
Tipsをご紹介します。弊社ではScalaが最大勢力のメジャー言語なので、Play frameworkでも
scalaを使ってみようと検証中です。

動的にリンクを作りたいケースがあり、テンプレートに実装していたのですが、Java版で書くと
下記のようなことをScala版でもしようとしました。

 <a href="@{Application.show(_post.id)}"><span>link</span></a>

参考URL:Playframework tutorial(Java)

このコードはJava版とScala版のリファレンスを見ると、Scala版にはサンプルコードがないのですが、
見る限りそのまんま使えそうに見えます。

参考URL:Scala templates

しかしながら、Scala版でそのまんま使おうとしたところ使えませんでした。
Application.showのリンク先がこのコードの部分でレンダリングされてしまうのです。

あれー、と思ってplay-scalaのソースをまさぐってみたら下記のコードを見つけました。

views.object in ScalaTemplate.scala

        def a(action: => Any)(body: => Html) = Html {
            var actionDef = new play.mvc.results.ScalaAction(action).actionDefinition
            if(actionDef.method == "GET") {
                """<a href="""" + actionDef.url + """">""" + body + """</a>"""
            } else {
                val uuid = play.libs.Codec.UUID
                """<a href="javascript:document.getElementById('""" + uuid + """').submit()">""" + body + """</a><form id="""" + uuid + """" action="""" + actionDef.url + """" method="""" + actionDef.method + """"></form>"""
            }
        }

この機能を使えばうまくいきそうです。
書いてみるとこんな感じですね。

  @a(Application.show(_post.id)){
    <span>link</span>
  }

動かしてみるときちんと動きました。

以上、Play framework(for scala)で動的リンクを作るためのちょっとしたTipsでした。

Posted in Scala, Tips, play framework | Leave a comment

NoClassDefFoundError:scala/Serializable when using multiple versions of Scala

This is esaulgd, application engineer at Geisha Tokyo.

A while ago, I was working on a web app developed with Scalatra and Maven. Suddenly, the following error started to pop up anytime I tried to build: (edited for brevity)

java.lang.NoClassDefFoundError: scala/Serializable
     at java.lang.ClassLoader.defineClass1(Native Method)
     at java.lang.ClassLoader.defineClassCond(ClassLoader.java)
     at java.lang.ClassLoader.defineClass(ClassLoader.java)
     at java.security.SecureClassLoader.defineClass(SecureClassLoader.java)
     at java.net.URLClassLoader.defineClass(URLClassLoader.java)
     at java.net.URLClassLoader.access$000(URLClassLoader.java)
     at java.net.URLClassLoader$1.run(URLClassLoader.java)

A Google search turned up no easily identifiable cause. Most people with similar problems found them to be related to building Lift, so I wondered whether there was an analogous issue with Scalatra. Just when it looked like I would have to roll up my sleeves and start messing with the build process, I found this article written in Japanese.

The article places the blame on simultaneous usage of multiple versions of Scala. When I checked, indeed there it was on the log output:

[WARNING] Multiple versions of scala libraries detected!

The reason I hadn’t made the connection is that this particular warning had been sitting there for months without any ill consequences. Well, until now.

As the problem had roots in the dependency chain deeper than the component I was in charge of, I brought the project lead into the fold. After some deliberation, we decided to make everything rely on the then-current Scala 2.9.0.

The “easy” part was to make sure that the web app, and all internally-developed upstream components, compiled using 2.9.0. In most cases this was as simple as editing the pom.xml as shown below and recompiling.

<project ...>
    <properties>
-      <scala.version>2.8.1</scala.version>
+      <scala.version>2.9.0</scala.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>${scala.version}</version>
        </dependency>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-compiler</artifactId>
            <version>${scala.version}</version>
        </dependency>
    </dependencies>
</project>

For externally-made components where a version for Scala 2.9 was available, we updated the dependency info. When this was not the case, for example with Scalatra (scalatra_2.8.1 ver 2.0.0.M3 at the time), we deployed a custom build to our internal repository.

<project ...>
  <properties>
-   <scalatra.version>2.0.0.M3</scalatra.version>
+   <scalatra.version>2.0.0-SNAPSHOT</scalatra.version>
    <scala.version>2.9.0</scala.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.scalatra</groupId>
-     <artifactId>scalatra_2.8.1</artifactId>
+     <artifactId>scalatra_${scala.version}</artifactId>
      <version>${scalatra.version}</version>
    </dependency>
    <dependency>
      <groupId>org.scalatra</groupId>
-     <artifactId>scalatra-scalate_2.8.1</artifactId>
+     <artifactId>scalatra-scalate_${scala.version}</artifactId>
      <version>${scalatra.version}</version>
    </dependency>
    <dependency>
      <groupId>org.scalatra</groupId>
-     <artifactId>scalatra-scalatest_2.8.1</artifactId>
+     <artifactId>scalatra-scalatest_${scala.version}</artifactId>
      <version>${scalatra.version}</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Once the entire chain was updated, both the warning and the error disappeared.

A possible explanation for this phenomenon lies with the compiler daemon. However, the Maven build wasn’t supposed to be using the daemon in the first place, so either there’s a fault there or another factor is at play.

In any case, having this information spelled out in English will hopefully help someone else.

Good luck and happy scala-ing!

Posted in Scala, maven | Leave a comment