小ネタ:文字列#replaceで簡易パースは便利だけどどうもね。

string#replace関数に、関数が渡せることをご存知でしょうか?

https://developer.mozilla.org/ja/Core_JavaScript_1.5_Reference/Global_Objects/String/replace

function replacer(str, p1, p2, offset, s)
{
  return str + " - " + p1 + " , " + p2;
}
var newString = "XXzzzz".replace(/(X*)(z*)/, replacer);

returnで返した文字列に置換されるというものですが、これを使って簡易パーサーを書くことが出来ます。

var str = 'banana,apple,orange',
    vals = [];

str.replace(/[^,]+/g, function(s) {
  vals.push(s);
});

console.log(vals); // ['banana', 'apple', 'orange'];

割と使われてる小技だけど、変態っぽいし「replace」って名前が気になるしそもそも内部で無駄な処理が走ってるはず。
なんで真面目にRegExp#execを使って頑張ってみる。
https://developer.mozilla.org/ja/JavaScript/Reference/Global_Objects/RegExp/exec

var str = 'banana,apple,orange',
    vals = [];

(function() {
  var r = /[^.]+/g, match;
  while ((match = r.exec(str)) != null) {
    vals.push(match[0]);
  }
}})();

console.log(vals); // ['banana', 'apple', 'orange'];

名前空間を汚さないように関数でくくるため、長くなる。くくらなくても1行長い。
しかも、string#replaceでパースする場合、以下のような見やすい書き方が出来る。

var str = '12:15-13:40',
    start,
    end;

str.replace(/(\d+:\d+)-(\d+:\d+)/g, function(s, hm1, hm2) {
  start = hm1;
  end = hm2;
});

console.log(start, end); // 12:15, 13:40

分かりやすいですよね。
しかし、同じ動きをする関数をexecで作るのがベターだとは思う。

input type="submit"のボタンを画像にする方法(IE対応)

input type="image"は要不要関わらずクリック位置がサーバに渡されちゃうし、IEだとnameとvalueの組がサーバに送られない。buttonタグでもIEは同じ仕様。
onclick="form要素.submit()"でいいじゃんと思うけど、ボタンの配置場所がフォームの内側だったら、javascript使うのも馬鹿らしいよね。
なので、input type="submit"をCSSで画像にしてみた。

<div>
  <input type="submit" name="hoge" value="fuga">
</div>
div {
  height: 16px; /* IE用 */
  overflow: hidden; /* IE用 */
}
div input {
  border: 0;
  margin: 0;
  padding: 16px 0 0 0;
  width: 16px;
  height: 0;
  background: url(../image/del.gif) left top no-repeat;
  overflow: hidden;
}

はい、divでくくりましたとさ……(諦め
IE以外のブラウザは、上記CSSのinputタグ用の部分を適用するだけで文字が隠れてくれるんだけど、IEだと隠れてくれずに縦に伸びて文字までしっかり表示される。なんで仕方なくdivでくくってhidden。
IEのinputタグの文字列はどうも色々特殊っぽくて、color: transparentでも消えない、font-size: 0にしてもゴミが残る、などなど、divでくくることにするまでかなりゴニョゴニョしたけど駄目だった。
なんかいい方法無いものか……。でもこれ、上述の通りjavascript使えば良い話で、あんまり真剣にハックしてる人いないだろうなとも思う。

雑誌記事書きました

一週間過ぎてた;

えーと、雑誌記事書きました。
Google APIについての概要部分を担当しました。
たまたまお話を頂いたときにお金が苦しく、二つ返事でお請けさせて頂きました。
興味があったら読んで下さいな。読むともれなく私の本名が明らかに!w

http://tech.ascii.jp/elem/000/000/601/601944/
http://tech.ascii.jp/elem/000/000/601/601704/dt_1106_s_230x.jpg

文章で食ってくのは大変だなーと思いました。面白そうですけどねー。

FileChannel#lock()は同一VMの複数スレッドでは使えない

ファイルシステムを扱うプログラミングは久しぶり。
で、今までnioをあんまり触ってこなかったのだけど、ロックかけたり触る機会があったので触ったら案の定ハマったのでした。

ファイルロックは Java 仮想マシン全体のために保持されます。これらは、同一仮想マシン内の複数スレッドによるファイルへのアクセスを制御するのには適していません。
ファイルロックオブジェクトは、複数の並行スレッドで安全に使用できます。

http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/nio/channels/FileLock.html

要するに、あくまでJava外からファイルを操作された場合を想定しているんであって、同じVMで動いているjavaプログラムはファイルを操作出来ちゃう。
あと、既にロックかかっているファイルをロックかけようとすると java.nio.channels.OverlappingFileLockException が発生。

んー、まぁ理解は出来る挙動だけど、そうなると例えばダウンロードスレッドを複数本立ててファイルダウンロードなんてのは、ファイルパスとロックオブジェクトを管理するstaticなマップオブジェクトでも作って……と今までと変わらない実装しか無いわけか。うーん。

そろそろブログを週一更新するとか宣言してみるか

技術系のネタを毎週やれればいいんだけど、最悪、妄想メモでの更新もアリとします。
何週間続くかな?

ということで、妄想メモ。

  • YouTubeでセカチャク
    • GAEで作りたいなーと。
    • まずは超簡単なプロトタイプを作ってみるつもり

ブラウザ毎のログインフォーム入力保存の挙動の違い

よくある、IDとパスワードを保存してくれて、ID選択するとパスワードも自動で入ったりするアレの、ブラウザ毎の違いです。ブラウザは全て最新版。

保存されるタイミング

  • IE
    • ログイン後、「保存しますか?」ダイアログ
  • FireFox
    • ログイン後、上部に「保存しますか?」バー
  • その他
    • ログイン後、自動で保存

同一ドメインで/hoge/loginと/fuga/loginを運用した場合

  • IE
    • ちゃんとそれぞれを別サイトとして扱う。
  • Opera
    • hogeとfugaを区別してはいるんだけど、1ドメインにつき1個しか保存できないので、hogeで入るとfugaの方が消える
  • その他
    • hogeでの入力情報をfugaの方に補完する。hogeでログインするとfugaの入力情報が上書きされ、逆もしかり。

対策(というか妥協案)

formやinputにautocomplete="off"をつけるしかない。

まとめ

まさかのIE大勝利。まぁ、外部向けのサービス作るときに、同一ドメインで複数のサービスを運用するかっつーと疑問だけど。

パーティショニングについてのメモ

新年明けましておめでとうございます。
今年もよろしくお願いします。
新年一発目でなんですが、MySQL 5.1以降の機能「パーティショニング」についてのメモです。

GAEでBigTableやらCassandraやらNot only SQL系に興味が移ってますが、RDBMSを使うべき場面をきちんと判断出来るようになりたいですね。