2009年 05月 01日

2009年 05月 03日

なんかどんどん頭が悪くなっていって嫌だなぁ…… 本当にどうしたらいいのだろうか……

帰省ついでに PASMO の払い戻しをした (関西では全く使えない……)。50円だけ残ってたのでコンビニで買いものして0に。なんか払い戻しするために名前とか電話番号とか書いて身分証明書まで要求されてdnbkした。定期作ったのがかなり前のため電話番号とか「どれ?」って感じだしとても困った。

あと SUICA を払い戻しして作りなおしたい。

そういえば京都のバスは全くICカードが使えなくてびびる (あんまり乘ってないから知らないだけなのかな?)。関東は箱根のバスでさえ使えるのになぁ……

お知らせ : 京都新聞

計画はあるんだなぁ。

というかバスとかかなりいっぱい走っているし、車内混んでるし、地下鉄の料金は距離を考慮すると関東の倍額ぐらいに感じるのに経営が苦しいってのはなんでなんだろう……

2009年 05月 02日

gerry++

2009年 05月 03日

一週まわって

ここで書くほうがいいかもなぁ。なぜか結局ここがアクセス一番多いっぽい…… 不思議だ。

Markdown がダメな感じなのではてキにしたらちゃんと使えるかもなぁ。

なんか左上の奥に親不知っぽいものが生えてきてびびってる…… ちょっとまえから「なんか盛りあがってるなー」と思ってたけど、ついに歯っぽい舌触りのものが……

タイトルをつけるのが面倒くさい

タイトルをつけるのが面倒くさいのだなぁと最近わかってきた。実際はてダのほうでは殆どタイトルをつけない…… あんまりよくないクセなんだけどめんどうなのはめんどうだと思う。


はてダでプライベートモードの日記を一つ作り、それに日記を書いて、ここのサイトはそのデータをインポってくるのがいいのかもしれない。タイトルはそのタイミングで本文から自動生成するとか

はてダは適当に sha1hex を回答としてなぞなぞ認証かければ、自分のパスワードを保存しなくてもAPIっぽい閲覧許可を得ることができる気がする。

でも更新かけるとき面倒だよなぁ。書いたあとにすぐ書きなおしたりとかよくするのでめんどうだなぁ


そもそも、ブログというものがとても嫌いなのにも関わらず、/blog とかいうURLにしたから悪いんだ!

2009年 05月 04日

SUICA の払い戻しもした。こっちは電話番号は必須ではなく、名前生年月日性別と身分証明書だった。買いなおしは今度関東圏いったときにする。

でもって ICOCA を買った。無記名のやつを持つのは何気に初めてだなぁ。

2009年 05月 05日

だんだん日記タイトルが長くなる (そしてセクションタイトルをつけない)

2009年 05月 06日

なんか変な刷り込みで流星レコード (marble) 聴いてると妙に京都にいる感じがする。実際いるんだけど……

2009年 05月 07日

今日は言葉にしませんでした、と言葉にしておきます

2009年 05月 10日

gerry++

ケータイがまたおかしい

  • 外部電源なしだと全く起動しない
  • 外部電源つけると勝手に起動しはじめて勝手に失敗してこれを繰り返す
  • 古いほうのバッテリだと正常に起動し、起動後に外部電源させば充電される

なんかこの機種は充電周りにバグがあるんじゃないだろうか……

前回と同じようなことをやったせいな気がする。こういうことすると再現しそうなのでしないようにしたい。

  1. ぎりぎりまで (Low Battery 警告) がでるまで充電しない
  2. Low Battery がでたら電源きる
  3. 電源入れないまま充電を開始する
  4. 1時間ぐらいすると再起動を繰り返しはじめる

新バッテリでも起動することができた。電源電流の問題のようだ。

USB → N73充電端子のものを普段使っているのだけど、USB の電流では足りないみたいだ? (あるいは USB だと変に流れすぎる?)

なので、一本 USB ケーブルを犠牲にして、安定化電源で 1A ほど供給してやったら起動できた。んだけど、微妙にハマったというか謎の挙動

  • 安定化電源の電流制限を 1.5A に → 接続時に一瞬で 1.5A まで流れてすぐ 0A になる
    • 安全装置作動?
  • 電流制限を 1A に → 問題なく起動 → 接続中、制限電流まで常時消費してる
  • 充電完了間近になると 1A と 0A と激しくいったりきたりする

Nokia 純正アダプタはスペック的には 5V/890mA 実測開放電圧 6V(端子が壊れていて使用できない)

テスターとか電源とか一通り持ってきてよかったと思うことが最近多々あります……

2009年 05月 11日

今まではマイナス方向に向かっていたものをギリギリで何かにすることをしていたけれど、そういった気持ちが少しずつ失なわれ、元々プラス方向に向かうものがないのも相俟って、全体的な力が低下しているように感じる。

まずは余計なことを考えずに日記を書こう。

2009年 05月 12日

少しずつ戻りつつはあるかな。

コードの確かさはそれこそ人の意見100%でもいいけれども (コードというのがコミュニケーションのためにあるのだと考えればそういうものだ)、せめて生きかた (全くの個人的なもの) ぐらいは、能動的に何らかの形を、自分で見つけるべきだろうと思う。

「見つける」というと、言いすぎな感じもする。何を組み合せるかを選ぶ程度だろう。

「Century Gothic」がなぜか全く覚えられなくて困る……

2009年 05月 11日

gerry++

tsocks 経由ってるかどうかプロンプトに表示するようにした

2009年 05月 13日

雨がふっているけど、ちょうどふきこんでこないので窓をあけてる。風にいい匂いがする。雨の匂い (実際は何の匂い?) というのは落ち着く。

Leopard 10.5.7 で Nokia N73 との Bluetooth 相性問題が解決された。

10.5.7 のリリースノートには特に Bluetooth のことについて書いてなかったので、ダメ元で試したみたんだけど、繋るようになった。Apple++ Leopard の悪口ばっかりいっててすいません

2009年 05月 14日

ショウガをどうしても食べたい気分だったので冷蔵庫に残っていた紅ショウガを食べた。

色ついてないショウガ漬けを普通に常備したい……

2009年 05月 13日

JavaScript の正規表現のメタ文字をエスケープ

String.prototype.replace は正規表現じゃないと ignore case しつつ global マッチとかできないけど、JavaScript には RegExp.escape 的なものがないのでメタ文字が問題になる。

var escaped = 'f[oo'.replace(/[\s\S]/g, function (_) {
    return '\\u' + (0x10000 + _.charCodeAt(0)).toString(16).slice(1)
});

'F[oobarf[oof[oo'.replace(new RegExp(escaped, 'gi'), 'xxx');

たぶんこれでいける?っぽい。正確にはメタ文字のエスケープではなくて、全部エスケープしてメタ文字を無効化しているだけですね。

ignore case しなくてよくて、search が空文字列に絶対ならないなら

'f[oobarf[oo'.split('f[oo').join('xxx');

とかもいいのかな。どんなケースでもうまくいくかまでけんしょうしていないです。(頭まわってない)

前提が抜けてて大変申し分けないのですが、

  • JS は日常的に使用される処理系がいくつもある
  • 仕様が決まっているとはいえ特定文字だけエスケープすると漏れがでる可能性がある
    • 少なくとも全ブラウザであらゆるケースをテストする必要がでてくる
  • そもそも全部列挙するのがめんどくさい

ので、最も安全で楽な形を考えた、という感じです。

2009年 05月 16日

宗教上の理由で、リア充的な人がカッコいいと思うようなことをできないので……

memo

自分が JavaScript を書くときの規約みたいなのは既にだいたい決まっていて、結局のところ

  • クラス作成ライブラリなどを使わない
    • → そのライブラリを使わなくなったときにいちいち移植する必要があるから
    • → 普通に function Constructor () {} と prototype への代入を使う
    • → 継承みたいなことは基本しない。プロパティにオブジェクトをもって delegate する。
  • DOM, Event 関係はライブラリを使う
    • → クロスブラウザはここらへんに集約されているので……
  • 小さな snippet を組み合せる
    • → 必要なものを必要な分だけ
    • → クライアントサイドなので、変なものをいれない
2009年 05月 18日

2週間連続で写真撮りにいってない。

2009年 05月 17日

WAF

結局、アプリケーション (not Web App = WWW 非依存) なものを Web っぽい部分とつなぐ Dispatcher (Router) があればよくて、あとはおまけっぽいので、HTTP::Engine + Router で WAF っぽい部分は終わりになるような気がした。

uri path -> 実際の処理 の受け渡しが複数ファイルを見ないとわからないようなのはよくない。あっちいったりこっちいったりめんどうくさいし、ある uri へアクションを設定したいだけのためにファイル1個おいたり、とても無駄だ。

app 部分はまた別のものだ。

整理して github におきました: http://github.com/cho45/Chord/tree/master

#!/usr/bin/env perl
package FooRouter;

use Chord::Router::HTTP;
use base qw(Chord::Router::HTTP);

# define views
use JSON::XS;
sub json ($$) {
	my ($res, $stash) = @_;
	$res->header("Content-Type" => "application/json");
	$res->content(encode_json($stash));
}

use Text::MicroMason;
sub html ($%) {
	my ($res, $stash) = @_;
	my $m  = Text::MicroMason->new(qw/ -SafeServerPages -AllowGlobals /);
	$m->set_globals(map { ("\$$_", $stash->{$_}) } keys %$stash);

	my $content = $m->execute(text =>  q{
		<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
		<title><%= $title %></title>
		<p><%= $content %>
	});

	$res->header("Content-Type" => "text/html");
	$res->content($content);
}

# routing

route "/",
	action => sub {
		my ($req, $res) = @_;
		html $res, {
			title   => "Hello",
			content => "Hello",
		};
	};

route "/my/*path",
	action => sub {
		my ($req, $res) = @_;
		$res->code(302);
		$res->header("Location" => sprintf("/foo/%s", $req->param("path")));
	};

route "/:author/", author => qr/[a-z][a-z0-9]{1,30}/,
	action => sub {
		my ($req, $res) = @_;
		html $res, {
			title   => "Hello",
			content => sprintf("This is %s's page.", $req->param("author"))
		};
	};

route "/api/foo",
	action => sub {
		my ($req, $res) = @_;
		json $res, {
			foo => "bar"
		};
	};

route "/die",
	action => sub {
		die "Died";
	};


__PACKAGE__->run;
package Chord::Router::HTTP;
use Any::Moose;
use HTTP::Engine;

use Exporter::Lite;
our @EXPORT = qw(route);

our $routing = [];

sub route ($;%) {
	my ($path, %opts) = @_;
	my $regexp  = "^$path\$";
	my $capture = [];

	$regexp =~ s{([:*])(\w+)}{
		my $type = $1;
		my $name = $2;
		push @$capture, $name;
		sprintf("(%s)",
			$opts{$name} ||
			(($type eq "*") ? ".*": "[^\/]+")
		);
	}ge;

	push @$routing, {
		%opts,
		define  => $path,
		regexp  => $regexp,
		capture => $capture,
	};
}

sub dispatch {
	my ($self, $request) = @_;
	my $path   = $request->path;
	my $params = {};
	my $action;

	for my $route (@$routing) {
		if (my @capture = ($path =~ $route->{regexp})) {
			for my $name (@{ $route->{capture} }) {
				$params->{$name} = shift @capture;
			}
			$action = $route->{action};
			last;
		}
	}

	my $req = $request;
	$req->param(%$params);
	my $res = HTTP::Engine::Response->new(status => 200);
	$res->header("Content-Type" => "text/html");
	if ($action) {
		eval {
			$action->($req, $res);
		}; if ($@) {
			$res->code(500);
			$res->header("Content-Type" => "text/plain");
			$res->content($@);
		}
	} else {
		$res->code(404);
		$res->content("Not Found");
	}
	$res;
}

sub process {
	my ($self, $request) = @_;

	$self->dispatch($request);
}

sub run {
	my ($class, %opts) = @_;

	HTTP::Engine->new(
		interface => {
			module => 'ServerSimple',
			args   => {
				host => 'localhost',
				port =>  3001,
			},
			request_handler => sub {
				my $req = shift;
				$class->new->process($req);
			},
			%opts
		},
	)->run;
}


1;
__END__

Web App なのか App + Web なのか……

テストを考えなければどっちでもいいんだろうけどなぁ。

アプリケーションロジック (いくつかのモデルの結合) テストと、HTTP まで含めた結合テストは、はたして別れてたほうがいいのかなぁ。

2009年 05月 18日

外国の夢を見た。自分自身がそもそも日本人ではなく、しかも少年だった。近くの倉庫に「メリス」と名前がついた核爆弾を誘導するための装置があった。大勢の親戚が倉庫にやってきた。女の子がいた。

2009年 05月 19日

IMK 版の AquaSKK 場所 memo

/Library/Input Methods/AquaSKK.app/Contents/Resources

2009年 05月 20日

Android 環境構築

やるだけやっとこうと重いました。

  • sdk を展開 → ~/sdk/android-sdk-mac_x86-1.5_r1
  • ~/sdk/android-sdk-mac_x86-1.5_r1/tools を PATH に追加

android コマンドが管理ツールらしい

$ android create avd --name test --target 2
# Android 1.5 ベースの AVD がつくられる
# 指定する id は android list でみれる

$ android list
Available Android targets:
id: 1
     Name: Android 1.1
     Type: Platform
     API level: 2
     Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
id: 2
     Name: Android 1.5
     Type: Platform
     API level: 3
     Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
id: 3
     Name: Google APIs
     Type: Add-On
     Vendor: Google Inc.
     Description: Android + Google APIs
     Based on Android 1.5 (API level 3)
     Libraries:
      * com.google.android.maps (maps.jar)
          API for Google Maps
     Skins: HVGA (default), HVGA-L, QVGA-P, HVGA-P, QVGA-L
Available Android Virtual Devices:
    Name: test
    Path: /Users/cho45/.android/avd/test.avd
  Target: Android 1.5 (API level 3)
    Skin: HVGA

$ emulator -avd test

するととりあえずエミュレータは起動する。コマンド名が攻めすぎててヒく

2009年 05月 22日

コマンドラインのmp3 id3 タグ編集ツール

linux のコマンドラインで id3v2 を編集するやつってたくさんある割にろくなものがなくて、文字化けしたり正しいフォーマットで書きこめなかったりするのだけど、とりあえず使える方法を見つけたのでメモ

eyeD3 をとりあえず使う。python で書かれた id3 タグ編集ツール。そこそこよくできているけど、正しく文字コードを扱わない。

$ echo $LANG
ja_JP.UTF-8

$ eyeD3 --version
eyeD3 0.6.14 (C) Copyright 2002-2007 Travis Shirk <travis@pobox.com>

$ eyeD3 --set-encoding=utf16-LE --to-v2.3 --artist "ふー" --title "ばぁー" foo.mp3 
foo.mp3 [ 6.01 MB ]
--------------------------------------------------------------------------------
Time: 6:34      MPEG1, Layer III        [ 128 kb/s @ 44100 Hz - Joint stereo ]
--------------------------------------------------------------------------------
Setting artist: ふー
Setting title: ばぁー
Converting tag to ID3 version v2.3
Writing tag...
ID3 v2.3:
title: ã°ãã¼          artist: ãµã¼
album:          year: None
track:  

UserTextFrame: [Description: Tagging time]
2009-05-21T15:39:24

というふうに、頑張って書いてくれるのはいいけど、自分で書いたやつをちゃんと読みだせていない。

とりあえず決め打ちでちゃんと書けてくれさえすればいいので

#!/usr/bin/env python

import eyeD3
import os, sys
from optparse import OptionParser

parser = OptionParser(usage=u'%prog [opts] target.mp3')
parser.add_option("-T", "--title",
    dest   = "title",
    action = "store",
    type   = "string",
)
parser.add_option("-A", "--artist",
    dest   = "artist",
    action = "store",
    type   = "string",
)
parser.add_option("-L", "--album",
    dest   = "album",
    action = "store",
    type   = "string",
)

(options, args) = parser.parse_args(sys.argv[1:])
if not len(args) == 1:
    sys.stderr.write("requires target.mp3")
    exit();
target = args[0]

tag = eyeD3.Tag()
tag.link(target)
tag.header.setVersion(eyeD3.ID3_V2_3)
tag.setTextEncoding( eyeD3.UTF_16_ENCODING )

if options.title:
    tag.setTitle( unicode(options.title, 'UTF-8') )
if options.artist:
    tag.setArtist( unicode(options.artist, 'UTF-8') )
if options.album:
    tag.setAlbum( unicode(options.album, 'UTF-8') )

tag.update()

os.execlp("eyeD3", "", target)

というのを非常に頑張って書いた。Python 無理です。

なんかこれだと foobar2000 で場合によって文字化けする。なんなんだろ…… 判定に失敗するんだろうか。

firefly (mt-daap) だと大丈夫なんだけどなぁ。なんで id3 をまともに付けられる/読める環境になってないんだろ

2009年 05月 23日

memo

$ command git log --pretty=format:"%ad %an" --date=short | grep cho45 | awk '{ t[$1] += 1 } END { for (u in t) print u, t[u]}' |sort
$ gnuplot << EOF
set xdata time
set timefmt "%Y-%m-%d"
plot "/tmp/dt" using 1:2 with lines
EOF

2009年 05月 24日

2009年 05月 25日

なんかものすごく大切なことを忘れてしまったなぁ……

2009年 05月 26日

何の才能もなくても日記ぐらい書かないとクズにもならず無になってしまいます。

単純に熱狂的に好きになれる相手、あるいは何かが欲しいものです。3次元に限ったことではなくて、2次元でも1次元でも4次元でもいいのですが、どうにもこうにもそこまで熱狂的になれないなぁと思う次第です。ういちゃんおれだー! 結婚してくれー!

近ごろは何をやっても、全く何の「オレッテバスゲー」感を味わうことができないので、どうしようもなく、写真撮ってはダメだ、コード書いてはダメだ、と出力がままらないばかりか、写真見てはハースゴイナーナンデコンナノトレルンダー、コード読んではリカイデキネーイミワカラネーで入力もままなりません。

悪いことの列挙は簡単すぎるので最近あったいいことを列挙しようと思います。

  • 昨日の昼食にでたサカナの甘露煮がとても美味しかった
    • 姿形のある魚を食べる機会が極めて少ないこともあり……
  • 4人ぐらいでマリカーやった。楽しかった
    • もっとハンドルを練習します
  • 夜に外出たときちょうどいい気温
    • 散歩したい

わからないこと

  • DB 設計の感覚
  • デザインパターン
  • 小機能多クラス・多ファイル主義

全く分からないのは、小機能多クラス・多ファイル主義で、心の底から全く感覚が実感できない。何が嬉しいんだろう。100行ないファイルがたくさんあっても見るのがめんどくさい。バッファ選択がめんどうくさい。簡単なことを複雑にやっている感じがする。うまいこと納得できるワンフレーズみたいなのがあればいいんだけどなぁ。説得力がある説明が欲しいなぁ切実に…… それを「良い」と思わないとちゃんと書くことができない。

そんなことはどうでもいいし…… 何にしてもセンスがない…… 日記を書きはじめたときから言っている気がする。本当に何のセンスもない……

それよりも、もっと他人に手紙を書くことに慣れないといけない。多への発言に慣れすぎてしまって、特定の相手にメッセージを送ることができないのは、人生でとても損をするし、いろんな人にレスポンスがいまいち悪いやつだなぁと思われる(ないし思われている)ことだろう。

アイデアを思いついたときに記録する方式から、何が何でも1日に1個アイデアを出すようにしよう。無理矢理でも出さないと少しずつ感覚を忘れそうだ。もっとアイデアに敏感にならないと…… アイデアに理想を高く持たないことが重要だ

SSH のパスフレーズ入力時に毎回尋ねてきて、入力しないとダメなようになっていればいいよなぁ……

こんな日は女生徒でも読んで寝ます……

久しぶりに読んでみたら乃莉さんが想像される…… 乃莉さんと結婚したい!

珊瑚樹の青い葉が窓から覗いていて、一枚一枚の葉が、電燈の光を受けて、強く輝いている。空には星がキラキラ。なんど見直しても、キラキラ。

あれ、こんな文あったのか…… と思うことが多々ある。何度読みかえしても発見がある。いつも思うのだけど、本をたくさん読むより、好きな本をもっと深く読みたいと思う…… もちろんたくさんを、深く読めるにこしたことはないけれど、あんまり文章読めないからなぁ……

庭の向こうの原っぱで、おねえちゃん! と、半分泣きかけて呼ぶ他所の子供の声に、はっと胸を突かれた。私を呼んでいるのではないけれども、いまのあの子に泣きながら慕われているその「おねえちゃん」を羨しく思うのだ。私にだって、あんなに慕って甘えてくれる弟が、ひとりでもあったなら、私は、こんなに一日一日、みっともなく、まごついて生きてはいない。生きることに、ずいぶん張り合いも出て来るだろうし、一生涯を弟に捧げて、つくそうという覚悟だって、できるのだ。ほんとうに、どんなつらいことでも、堪えてみせる。

ぼくがいつも考えていることは「努力」をしない、ということだ。本当に、これだけは守らなければならない。いつもそういう「努力」という一言に片付けられた「何か」を探し求めていたのに、誰も答えを教えてはくれなかった。だから少なくともぼくは「努力」ではなく具体的な「何か」をしていかなければならないし、それを記録しなければならない。何の役にも、誰の役にも立たなくとも、必要なことだ。

バカの一つ覚えですよ! ハハ! ぼくはバカですから! バカであることを偉そうにいうな! ってアタマイイ人に言われます!

一番いま興味あるのはスケーリング方法かなぁ…… GAE とかも興味があって触ろうとしてるけどまだ手をつけてない。

調子が戻ってきた。いい感じだ。クズの自覚を持たないと生きていけない。

gerry++

2009年 05月 27日

部分適用・メソッド呼びだしの syntax suger・デフォルト引数

メモメモ。簡単な Singleton Logger を実装してみる

//#!scala

object Logger {
	var level = 0

	def log (message: String, level: Int) {
		if (this.level <= level) {
			println(message)
		}
	}

	def log (message: String):Unit = log(message, 1)

	def debug = log(_: String, 0);
	def info  = log(_: String, 1);
	def warn  = log(_: String, 2);
	def error = log(_: String, 3);
	def fatal = log(_: String, 4);

	// この例の場合はこうしたほうがいい気がする
	// def log (message: String):Unit = info
}

Logger.level = 1

Logger debug "debug"
Logger info "info"
Logger warn "warn"

部分適用は _ と型さえ書けばいいっぽい? 引数の順番に制限はないようだ

Logger foo argLogger.foo(arg) の syntax sugar らしい。引数一つのときに省略ができるというルールではなくて、レシーバも含めた syntax sugar のようだ

デフォルト引数は Ruby とかのように仮引数に書くことはできなくて、overload で定義するっぽい。このとき overload する側のメソッドは、返り値の型の宣言が必要らしい

gerry++

二日連続

2009年 05月 28日

GDHM の「陽だまりを越えて」を買ってきた。これからも楽しみだなぁ。発売日を意識して買うアーティストは唯一 GDHM だけです。

したいことがあったら声に出せ、というのが印象に残っていて、微妙に実践しようと思ってどうすればいいかなーという感じだったけど、「GAE やるんよ、やりたいんよー」っていってたら datastore のクセのイメージをタイミングよく教えてもらえたらいしたので、こういうことなんだなぁと思った。

一番嫌なのはやっぱファイルが増える、ということなんだと実感した。Scala で Java ラップするために沢山クラス作っても別に嫌ではない。ファイルが増えるだけで普段の作業のオペレーションが増えるんだもんなぁ…… 開く・閉じる・選択する・grep する。

GAE はとりあえずローカルの開発サーバが起動して、Scala で書いた HttpServlet に dispatch は簡単にできた。java class の自動コンパイル・自動リロードとか、リクエストフィルタを使った URL の dispatch とかが解らなくてとまってる。Lift とか読みつつやってるけど、そもそも Java war の流儀がよくわからない。

Scala だと Java の資源が使えるのが本当にとてもよくて、Rhino とか使ってスクリプト実行させたりもできるし、JRuby をテンプレートエンジンのためだけに使う (謎の XML 書きたくないし……) とかいう贅沢もできそうで夢が広がる。

Java は単体で書きたいとは全く思わないけど、Scala は書いていてすごく楽しい。ピタっとハマっていく感じがする。Ruby とかにはない型厳密な関数っぽい感覚。でも関数型ほど新しい考えかたをしなくても書けるから気持ちいい。しかも Scala はコンパイルすると Java クラスに変換されて JVM で直接動くのだから、JVM もすごいなーと思った。

gerry++

三日連続

スカラクロウラ - アクター

うーんよくわからない。while(true)/receive と loop/react の違いもよくわからない (スレッド作るかそうじゃないかだけの違い?)

クローラっぽいのを練習がてら書いてみた。あんまりわかりやすくはないなぁという気もする。もっといい書きかたあるのかな。

  • 一度に走るリクエストは2つまで
    • あらかじめ2つリクエストを出す Actor を作ってそれのキューにいれていく
  • List あたりが微妙にわかりにくい。普通に shift/push したい

http://gist.github.com/119257

あれこれ最初、スカラクロウラとかエントリで言いたかっただけだったのに、全くそんなこと忘れてエントリ書いてた

MP3 ID3 文字コード関係を仕様書にあたってみる

仕様がどうなっていようと使ってるやつが対応してないと意味ないですけどね!!

ID3v1

http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm#MPEGTAG

  • 文字コードについて記述なし
  • title, artist, album それぞれ 30bytes しか書けない

ID3v2

2.3

http://www.id3.org/id3v2.3.0

  • If nothing else is said a string is represented as ISO-8859-1 characters in the range $20 - $FF. Such strings are represented as , or if newlines are allowed, in the frame descriptions. All Unicode strings use 16-bit unicode 2.0 (ISO/IEC 10646-1:1993, UCS-2). Unicode strings must begin with the Unicode BOM ($FF FE or $FE FF) to identify the byte order.

要は

  • ISO-8859-1
  • UTF-16
  • UTF-16BE

でしか書けない。

2.4

http://www.id3.org/id3v2.4.0-structure

   Frames that allow different types of text encoding contains a text
   encoding description byte. Possible encodings:

     $00   ISO-8859-1 [ISO-8859-1]. Terminated with $00.
     $01   UTF-16 [UTF-16] encoded Unicode [UNICODE] with BOM. All
           strings in the same frame SHALL have the same byteorder.
           Terminated with $00 00.
     $02   UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM.
           Terminated with $00 00.
     $03   UTF-8 [UTF-8] encoded Unicode [UNICODE]. Terminated with $00.
  • ISO-8859-1
  • UTF-16
  • UTF-16BE
  • UTF-8

で書ける。場合によっては ISO-8859-1 と UTF-8 でしか書けない場合がある? (Tag restriction あたり。よくわからない)

個人的なベスト

  • ID3v1 は書かない
    • 今時 ID3v2 に対応してないプレイヤーとか捨てればいい
    • 文字化けの元
  • ID3v2.3 にしておく
    • 文字コードは UTF-16(LE)
2009年 05月 29日

web.xml filter, 自分で Dispatch

Lift 見つつ最低限な部分を自分で再実装

  • 全部のリクエストを受け取ってなんかしたいなら filter を使う
  • filter では、何もせずに chain.doFilter すれば static ファイルとかをいい感じにやってくれる。

web.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
	<filter>
		<filter-name>HttpRequestDispatcher</filter-name>
		<filter-class>net.lowreal.skirts.HttpRequestDispatcher</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>HttpRequestDispatcher</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>
package net.lowreal.skirts

import javax.servlet._
import javax.servlet.http.{HttpServlet, HttpServletResponse, HttpServletRequest}

class HttpRequestDispatcher extends Filter {
	val static = """^/(?:css|js|images|static).*""".r

	def init (filterConfig: FilterConfig) = {
		println("init")
	}

	def doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) = {
		println("doFilter")
		(request, response) match {
			case (req: HttpServletRequest, res: HttpServletResponse) =>
				println("")
				println(req)
				req.getRequestURI match {
					case static() =>
						println("static")
						chain.doFilter(request, response)
					case _ =>
						println("dispatch")
						res.setContentType("text/html")
						res.getWriter.println { """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">""" }
						res.getWriter.println {
							<html>
								<head><title>Hello World</title></head>

								<link rel="stylesheet" type="text/css" href="/css/base.css" media="screen,tv"/>
								<!-- script type="text/javascript" src="/js/site-script.js"></script -->
							<body>
								<h1>Request</h1>
								<pre>Method: { req.getMethod }</pre>
								<pre>RequestURI: { req.getRequestURI }</pre>
								<pre>QueryString: { req.getQueryString }</pre>
								<h1>Raw</h1>
								<pre>{ req }</pre>
							</body>
							</html>
						}
				}
			case _ => chain.doFilter(request, response)
		}
	}

	def destroy () = {
		println("destroy")
	}
}

skirts っていう名前で簡単なフレームワークを作ろうと思ってる。とりあえず Lift は気にいらなかったので、コードは参考にしつつも使わない方向に……

skirts = scala / 周りをとりまく何か / 美少女

2009年 05月 30日

はてブの非表示ユーザ関係の Greasemonkey script

  • 「うぜーなー」と思っても、永遠に非表示になってしまうと思うと非表示に入れにくい
    • → もっとカジュアルに非表示に追加したい
  • 非表示にしたときが、たまたまつまらないタイミングというだけだったかもしれない
    • → ずっと非表示なのは本位じゃない

ので3ヶ月で非表示ユーザを期限ぎれにして解除するユーザスクリプトを書きました。

http://gist.github.com/raw/117826/2085144424e6d5cd1e8cc93f74c988a8d81256ac/hatena.bookmark.expire_ignore_user.user.js

はてブの設定ページもついでに拡張していて、追加したユーザについて一覧できるようにしてあります。

  • いつ解除されるか、とかのデータははてブの custom_style にコメントとしてうめこんでいます
    • custom_style は公開情報なので、AES で暗号化しています
    • その関係で最初に起動したときキーを作ります
    • そこまでしなくてもいい気もしたのですがやっても損はしないのでやってみました
  • 設定ページから非表示ユーザを追加できなくなる (殆どしないし……)
  • 設定ページのリストで期限を再設定できる
    • 期限がすくなくとも生きている間にはこないようにできるように
  • 1日に1回 (はてブにアクセスしたとき) 非表示ユーザの更新をチェックして更新をかけます。
    • なので微妙にズレが生じます
  • 作ってから3ヶ月経ってないので使い勝手はわかりません


あとついでに「あるエントリをブックマークしているユーザ」を一括して非表示に追加できるスクリプトも書きました

http://gist.github.com/raw/117376/d7d23472e1af915df608d6f4f611998704723639/hatena.bookmark.ignoreentriesuser.user.js

ボタンがエントリページにでてきます。一度 confirm できかれます。

2009年 05月 31日

  • 下御霊神社
  • 梨木神社
  • 首途八幡宮
  • 白峯神社

余計なことを喋りすぎます……

はてダのタイトルってどんぐらい入力できるんだろ……

ひきこもるにはまだ早すぎるなぁ……

思うところ

Scala らしさ、というのがよくわからない。Scala であってもクラス作りまくってほげほげするという Java らしさを受け継ぎつつ書くのがいいんだろうか。というより Java のライブラリを利用すると自然とそうなってしまう……