Unicode実態参照をUTF-8文字列に変換

Unicode実態参照をUTF-8文字列に変換するという処理が必要になった。
標準添付ライブラリに使えるクラスが当然あると思って探したけれど、無い…。

ググった結果HTMLEntitiesを発見。

インストールは

gem install -r htmlentities

使ってみる

import "rubygems"
import "htmlentities"
$KCODE="u"

変換結果 = HTMLEntities.new.decode(変換前)

超簡単。

ちょっと考えてみると、外部のライブラリを使わなくても、

変換結果 = 変換前.gsub(/\&#(\d+);/){[$1.to_i].pack('U')}

でいける。
この例では実態参照が16進表記に対応していないけれど、対応してもたいしたことない。

標準添付ライブラリに含めないのは、この程度の処理は車輪の再発明しろということなのか。

NetBeansのScalaサポート

久しぶりにScalaをいじってみた。かなり忘れていて愕然とする。ある程度の規模のアプリを書かないと身に付かないということか。
以前に使った時には使い物にならない感じだったNetbeansScalaプラグインがだいぶ良くなっていた。
Netbeansが6.1の時には開発ビルドでしか使えなかったが、6.5には間に合うのかなぁ。
良くなったとはいえ、まだ注文あり。

デバッガ

ブレークポイントが設定でき、変数の状態をワッチできるようになったのは嬉しい。
しかし、ブレークポイントで止まらない時がある(再現条件わからず)。
また、ステップ実行でも数行飛んでしまうことがある。

コード補完

val s = "abc"

と宣言して、「s.」 と入力するとStringクラスのメソッドが候補として表示される。素晴らしい。
しかし、「"abc".」と入力してもObjectクラスのメソッドしか表示されない。何故?
Scalaの場合は 「.」を省略した「オブジェクト[空白]メソッド」という記述も許されるので、スペースを入力した時も候補が表示されるべきかな?(賛否分かれそうではある)

class FooString(s: String){
  def foo = s + "foo"
}
implicit def fooString(s:String) = new FooString(s)

とStringクラスにfooメソッドを追加した時には、Stringクラスのメソッド候補にfooも出てきて欲しいところだが、今後に期待。

JJUG CCC

JJUG CCCに行って来た。

参加できなかったセッション

Grailsセッション・Jruby on Railsセッション・ひがやすをさんのセッション等も聴きたかったけど、ちょっと余裕のない状態だったのでScalaのセッションだけ参加。
ひがさんのセッション「ITゼネコンをぶっつぶせ」、今の体制のままだと日本のソフトウェア産業は終わると思ってるので聴きたかったなぁ。セッション内容が「IT ゼネコンをぶっつぶすための秘策として、Programming First Developmentを紹介します。」ってなっているけど、これで変わるのかなぁ(ちょっと悲観的)。変わってくれるといいけど。それ以前に"Programming First Development"が受け入れられるか。顧客と営業がこの新しいやり方を受け入れるかが問題。

Liftセッション

Liftについてはほとんど知らなかったので、RailsっぽいのをScalaで実装したのかと思っていたけれど結構違っていた。同じようなのばかりじゃ進歩が無いのでいいことです。ERBやJSPのようにViewにLogicが入るのが嫌というのは分かるけど、ModelがHtmlのタグを作るってのも違和感あり。ViewにLogicを持たせないだけなら、RubyならAmritaJavaならMayaaなどの方法が美しい気がする。実際に使ってみると評価が変わるかもしれないけれど。
セッションの主題は、エンタープライズ用途で使える言語としてのScala
COBOLJavaScalaとなるか。Javaに対するアドバンテージは生産性だけだからちょっと苦しそうだけど。
フレームワークの記述はしやすそうだから、Lift以外にも色々なフレームワークが出てくれば可能性はあるか。

Scalaセッション

Liftセッションも結構人が多かったけど、こちらは大入り満員。入場に手間取って時間が押して、ただでさえ持ち時間の少ないスピーカーの方には気の毒でした。
水島さんのセッションは自分レベル(RubyJavaが使えて関数型言語の知識が多少ある)に丁度いい内容でした。Javaしか知らない人にはちょっと辛かったかも。
関さんのActor解説。Erlangより良さそうなので、Erlangを勉強するモチベーションが下がりました。Scala勉強しよ。
EricさんのScala specsの解説。英語が分かりやすくて一瞬自分のヒアリング能力が上がったかと思ってしまった。日本在住なので日本人相手に分かりやすく話すのに慣れているようです。Scala specsは、なかなか良さそう。
関数型言語は手続き型のようなブレークポイント、ステップ実行等のデバッグ手法が取れないのでテストさらに重要ですね。

うーん

毎日新聞トトビッグ:繰越金47億円 なぜ増えぬ1等「6億円」という記事。

コンピューターの数字の組み合わせは、試合結果3通りを14乗(試合数)した480万通りとなり、理論上は、当選確率も480万分の1。ジャンボ宝くじの1000万分の1に比べると、当選確率は2倍以上だ。

理論上って、どんな理論?
この記者は、イチローが打席でホームランを打つ確率は[打つ,打たない]の2通りだから1/2だと思っているのだろうか。
7面体の将棋の駒を投げて逆さに立つ確率は1/7と思っているのだろうか。
こういうウソをマスコミが流すと信じちゃう人がいるから困るんだよね。


しかし、トトビッグの出目は完全にランダムなのかなぁ。
操作すればいくらでも当選確率変えられそう。

これはひどい

C/C++のポインタの機能--参照渡しのような処理という記事。これほどひどいポインタの説明は始めて見た。
このライター、Groovyの唯一の日本語解説本(『スクリプティングwith Java』の一部だけど)の著者なんだよなぁ・・。
買わなくて良かった。

久しぶりの

このところ仕事で死んでました(私生活でも色々・・)。
はまっていた仕事はc#(.NET2.0)。前にやったc#の仕事は .NET1.0 だったので色々変わってた。
それ以前にc#を忘れてた。まあすぐ思い出したし、2.0になってからの機能は便利に使った(3.0の機能は目の毒なので見なかったことに)。
しかし思い出せない(ってか、そもそも覚えていない)のはクラスとメソッド。
IDEのエディタはデバッグ時にブレークポイントを設定するためのもの、と認識しているのだけど、今回はIDEのコード補完を大変便利に使いました。
しかし、デバッグ.NET Frameworkのソースにもぐれないのは困る。MFCの時にはMFCのソースにStep inしてバグを見つけて回避したことがあるから、.Net Frameworkも信用していない。今回も怪しい挙動の回避に苦労した。
.NET3.0ではソースが公開されたようなので、同様の不満が多かったのかな。

GroovyとRuby

前回作ったマクロはjFD2の作者にも使ってもらえたようだ。
で、「ファイルの表示順を大文字小文字を区別しないようにして欲しい」とのリクエスト。検索では大文字小文字区別していないのだから当然の要求である。自分では小文字のショートカットしか使っていないので気付いていなかった。
該当部分は

files=files.sort()

とりあえず

files=files.sort(){x,y->x.toLowerCase()>y.toLowerCase()?1:-1}

とした。JavaならComparetorを実装して渡すところだしGroovyでも同様にできるのだが、たぶんクロージャを渡してもOKだと思ってやってみたら問題なし*1
後で、リファレンスを見るとRubyのように"<=>"演算子が使えるようなので

files=files.sort(){x,y->x.toLowerCase()<=>y.toLowerCase()}

でもいい。
しかし、ほんとはRubyの"sort_by"メソッドのように記述したかったので"sortBy"とか探したけれど見つからない。
そこで、物は試しと

files=files.sort(){it.toLowerCase()}

で、あっさり出来た。
現時点の最新のリファレンスを、どう読んでもこんな書き方が出来るようには解釈できないのだが・・。
実装にドキュメントが追随しきれないのは何処も同じとはいえ、現時点のGroovyのバージョンは1.5でjFD2に同梱されているバージョンは1.1。1.1での機能くらいは網羅していて欲しいところ。


Groovyの日本語で読める資料を探すとGroovy - Java用スクリプト言語にたどりつく。訳者が角谷さんなのでRuby使いとしては安心して読める。
とはいえGroovyが1.0になる前の資料を訳した物なので、今のバージョン(jFD2の1.1でも)ではエラーになる記述を今のところ2つ見つけた。
(1) クロージャの記述


クロージャを定義する文法は、

{ comma-separated-parameter-list | statements }

との記述があるが、実際は

{ comma-separated-parameter-list -> statements }
でないとエラーになる。


(2) Range(範囲オブジェクト)の記述

3..7 は「3 から 7」を表す Range を生成する。
3...7 は「3 から 6」を表す Range を生成する。
との記述があるが、3...7はエラーになる。


上記2点、エラーになる記述はいずれもRubyと同じ書き方なのだが、それを1.0以降のバージョンで敢えて変えたのは何故なのか、ちょっと気になる。

*1:先にリファレンスを調べるべきなのだが、実家のネット環境が貧弱なので、オフラインで試せることは先