2008-05-08
■ [tDiary] accesskeyを潰した
どうも、ボタンにaccesskey属性が指定されてるかららしい。
<span class="button append"> <input type="submit" tabindex="999" accesskey="A" name="<%%= submit_command %>" value=" <%%= submit_label %> ">
まあキーボードからボタンが押せるのは便利だけど、、、C-aはないよC-aは。
とりあえず、skel/edit.rhtml, skel/preview.rhtmlを書き換えて対処した(very 場当たり)。
http://d.hatena.ne.jp/kwatch/20080413/1208098168 のパッチが採用されるといいな。
■ [event][scala] Scala勉強会@岡山-1 行ってきた
帰省コースどまんなかだったんで寄ってきました。
Scalaの感想とか
variance指定(いまだによく分かってない)とかマニアックな機能が入ってるわりに、実用指向なんですよねこれ多分。Javaの巨大な標準ライブラリがそのまま使えるわけだし。 XMLリテラルとか入ってるし(笑) C系文法だけどパターンマッチがあるとか、 そのへんのギャップが面白いなと思いました。Scalaがバリバリに実用される世界では、みんなどんなコードを書くんだろうか。
懇親会とか
ふだんJavaな人と話さないので面白かった。Javaクラスタ。
moriqさんからRailsのテストの話を聞いた。規模が大きくなるとテストの実行時間が伸びて辛い。解決方法は2つ。(1) Rspec server(?)みたいなものを使って、 テストの起動時間を短くする。 (2) fixtureとか使うといちいちDBへのアクセスが入るので遅い。DBにアクセスしないように、モデルのモックを作って、 コントローラのテストのときはそれを使う。 (←Scala関係ないぞ)
以下、ログです。
■ [event][scala] Scala勉強会@岡山-1 ログ
- 原因はJava-ja
自己紹介
- keisuken
- Java, Ruby, JS, ASなど
- jspit
- GB単位のファイルの分割ツール(by Scala)
- Ruby/PureImage
概要
- http://www.scala-lang.org/
- 静的型付け(型推論あり)
- コンパイル型
- OOP+関数型
- 頻繁にバージョンアップされている
- Javaと.NET上で動作する(が、.NET版は停滞中)
- リーダーはスイスのローザンヌ工科大学に (javacのGenericsに関わっていた人物)
- Javaとおなじところ:
- Erasureな(コンパイル時には型がわかっているが、実行時には分からない(??))Generics
- Javaと同等のパフォーマンス
- 型システム(Javaから継承)
- クラスファイル
- Javaとちがうところ:
- すべてがオブジェクト(数値も)
- 型推論、クロージャ、パターンマッチ
- Implicit Conversions(Views) (あとで)
- scala = インタプリタ兼REPL
- scalac = コンパイラ
object Hello extends Application{ println("Hello.") }
- javap Hello.class →JVM上でのクラス(?)が見える
- scaladoc
- 標準ライブラリ: 豊富なコレクション、Actor、パーザコンビネータなどなど
文法
リテラル
- 文字列 : "Foo\nBar"
- ながい文字列(ヒアドキュメント代わり) : """ほげほげ(改行もOK)"""
"""Foo |Bar """.stripMargin ←「|」までの空白を取り除いてくれるメソッド
- 数値 : 1234, 1234l (long), 1.2 (Double), 1.2f (Float), 1.2e10 (Double)
コメント
- 行コメント : // ほげほげ
- ブロックコメント : /*ほげほげ*/
- ScalaDoc用コメント : /** ... @param foo value */
代入
- var i = 1234 //再代入可能
- val i = 1234 //再代入不可(関数型的なかんじ)
- var i: Int = 1234 //型を明示することもできる
分岐
- if : Javaのif文相当。ただし式である(値を持つ)。
- 例: val length = if (str != null) str.length else 0
- match : パターンマッチ。switch文より柔軟
ループ
- for文 : Javaの拡張for文のような感じだが、filter/map用途にも使える
for (i <- 0 until 10) { //foreach的な例 printf("{0} ", i) } val strs = for (v <- values) yield { v.toString } //map的な例
- while, do while文 : Javaとほぼ同じだが、continue/breakがない
クロージャ
//例: foreachメソッド (メソッド呼び出しの「.」は、曖昧でなければ省略できる) 0 until 10 foreach {i => printf("{0} ", i) }
XMLリテラル
- きもーい(笑)
- val h1 = <h1>Hello, world!</h1>
- 中括弧を使うと値が埋め込める
val html = <html><body>{ for (value <- Array(1,2,3)) yield <p>{value}</p> }</body></html>
メソッド
- オーバーロード可能
- 一行でも書ける
def foo(str) = "Foo" + str
クラス
- コンストラクタはthis //def this() = this("", "")
- 暗黙にScalaObjectを継承する
- override def toString = ... //と書かないとコンパイルエラー
object
- シングルトン(インスタンスが一つだけ)なクラス。mainメソッドはここに書く
trait
- Javaのinterfaceのようで違うもの (Rubyのmoduleに近い?) 実装が書ける
- 実装を省略すると抽象メソッドになる
パッケージ
- 名前空間。Javaとほぼ同じ。
- package com.examples.foo で Fooを定義→com.examples.foo.Foo
- 取り込みは import で (import java.util.{List,Map} とか, import java.util._とか)
- 変数もimportできる(jsのwithみたいなものか?) val foo = new Foo → import foo
例外
- try{ .. } catch { case e: FooException => .. } finally { .. }
- throw new FooException(..)
パターンマッチ
- Haskellのような
- オブジェクトに対する正規表現のような
val foo: Any = 233 //AnyはJavaのObject型みたいなもの case class Name(name: String) //case classはmatchで使う用のクラス
foo match { case v: Int => .. case v: String => .. case _ => .. case Name(v) => .. }
Implicit conversions
- 型変換とか、型の拡張に使われる機構
implicit def int2str(value: Int): String = { //このメソッド名は何でもいいっぽ(型が重要) value.toString } val value: String = 1234 //うまくいく!
- 型の拡張の例
implicit def person2father(p: Person) : Father = new Father(p)
val person = new Person() val children = person.children //自動的にPersonからFatherが作られる
デモ
- ベンチマーク
- ツール
- Ant Scala task, Maven Scala plug-in
- ライブラリ
- Spec, Lift(webフレームワーク)
第一部まとめ
- Javaとの親和性大
- パフォーマンスもそこそこ
- 便利な文法やAPI→LightWeightな開発
- JavaでできることはScalaでできる!(Web、GUI、マルチメディア…)
余談
- Javaだと軽量に書けない…というわけではないよね
- 言語の改良、Eclipse、軽量指向なフレームワーク
- Javaには実績がある
- Scalaは楽しい
質疑応答
- Scalaのキラーなメリットってない?他の言語で絶対できないような
- ないと言ってもいい。今のところは。誰も発見/発明していない
- DSLとか?
- Java APIでできることはJavaでも出来るわけだから、実績がない分Scalaが不利
- Perl/Python/Rubyに対してなら、静的型(かつ軽量指向であること)がメリット。あと速度
- Lift -> Apache, Tomcat,
- 基本的にはJavaの環境をそのままつかう
- O/RマッパーはLift独自実装(ActiveRecordぽい) 中身はJDBCかも
応用
もっと濃い文法 : 遅延評価
- lazy val okButton = new JButton("OK") //okButtonが使われたときに生成される!
- 相互参照
lazy val a = (bを参照するなにか) lazy val b = (aを参照するなにか)
演算子の再定義
- 単項演算子 : + - ! ~
- def unary_+ : Num = new Num(value)
- 二項演算子 (優先順位は変えられない)
- def +(v: Num) = ...
scala.Predef
「_」(Perlの$_みたいな)
- 1 until 10 foreach { println(_) }
カリー化されたメソッドの定義
- def open(file: String) (p: InputStream => Unit) { // fileは文字列型、pはクロージャ
- 使うときは open("foo.txt") {in => ... }
- openに "foo.txt"を渡し、その結果にクロージャを渡している
高階関数
- def calc(f: (Int,Int) => Int, x:Int, y:Int) .. // fは2つの整数を受け取ってIntを返す関数
- Javaではメソッドを型につかえないので、内部でいろいろしている
Generics
- val array = new Array[String](10)
- array(0) = "foo" //配列の添字は()で表す
- 定義側は class Foo[T] (var value: T) とか (Tは型。型は使うときに指定する)
アノテーション
- Javaのとはいろいろ異なる
- @throws(classOf[IOException]) def open(...)
Actor(軽量プロセス)
- 標準添付
- Erlang由来? 非同期メッセージパッシング
- 10Actorくらいを1スレッドが担当→JVによりマルチコア対応!
- actorというメソッドがある
actor { for (i <- i1 to 10) { println("a: " + i) Thread.sleep(1000); } }
- 送信: foo ! i + 1
- 受信: receive{ case i: Int => .. }
これ以降のログは取れていません。資料公開に期待しましょう:-)
>パッチが採用されるといいな。<br>遅くなりましたが trunk でパッチを採用しました。
ありがとうございます。<br>tDiaryにはいつもお世話になっていますm(__)m
冷蔵庫が無いような気が。。。
冷蔵庫は書き忘れですねw