2008年 05月 13日

Io って頭おかしいなぁ (いい意味で)

curlyBrackets を知った。

Object curlyBrackets := Object getSlot("method")

foo := {
	"aaa" println
}

bar := {a,
	"bbb" println
	a
}

foo

bar(getSlot("foo")) # method は普通に書くと実行されてしまうので getSlot する必要がある。
aaa
bbb
aaa

ちょっと他の言語に近づいた感じ。

もう少し変態的にしてみる

def foo (mes) {
    mes println
}

こういうふうに書けるようにするために def メソッドを定義する

def := {
	name := call message next name
	args := call message next arguments map(i, i name)
	meth := call message next next
	next := meth next

	# cut message chain
	meth setNext(nil)

	# set the method to caller context
	call sender setSlot(name, call sender doMessage(meth))

	# set arguments list
	call sender getSlot(name) setArgumentNames(args)

	# pass to next message
	call message setNext(next)

	# return the method
	call sender getSlot(name)
}
# 引数なしなら仮引数省略可
def hogehoge {
	"hogehoge" println
}

def piyopiyo (mes) {
	mes println
}

# 引数なしなら括弧いらない
hogehoge
hogehoge()

# 引数ありなら括弧必須
piyopiyo("foobar")

Foo := Object clone do (
	def foo (mes) {
		mes println
	}
)

Foo foo("alert")

書いた式がどうコンパイルされたかは (前にも書いたけど) 以下のようすればわかる。

Message fromString("def foo (mes) { mes println }") code println
#=> def foo(mes) curlyBrackets(mes println)

call message は呼びだしもとのメッセージチェイン (def foo(mes) curlyBrackets(mes println)) をさしてる。call message next は今のチェインの次、すなわち foo(mes) curlyBrackets(mes println) で、call message next name で先頭のメッセージの名前がとれる。メッセージを自分でとって doMessage することでメソッドを作って、呼びだしもとのコンテキストにセットする。setNext でメッセージをチェインを切ったり、スキップしたりする。

実際もっと簡単に

def := method(
	ret := Object clone do (
		foo := method(
			self args := call message arguments map(i, i name)
			self
		)

		curlyBrackets := method(
			meth := method() setMessage( call message argAt(0) ) setArgumentNames(args)

			context setSlot("foo", meth)
		)
	)
	ret context := call sender
	ret
)

def foo () {
	"faaa" println
}

foo

とかだと、method_missing 相当がないのでうまくいかない。(これは動くけど、foo 決めうちだからうごいてる)

method_missing に相当するのは forward だった

2008年 05月 10日

window.moveBy の時代がくる、こない

ページ内要素のドラッグでウィンドウうごかす http://lab.lowreal.net/test/mmm.html

なんかもっとおもしろいことできそうだなぁ。うざくならない程度におもしろいのがしたい。

2008年 05月 08日

gerry++

ひどかった。海老名で途中下車

2008年 05月 04日

楽しく写真撮りつつあとでどうにかする

あんま写真撮ってるとき (外にいるとき) に神経質になりたくないので RAW で撮っております。階調と被写界深度だけ気をつけてホワイトバランスとかカラー設定とかあとからどうにかなる部分は全部オートです。撮って出しに価値があるように思わないなぁ。連続撮影枚数超えるような撮影するようになったら違うのかなぁ……

RAW 読みこみデフォルト (カメラ側の AWB がかかってる)

ホワイトバランス修正で全体的な雰囲気をイメージに合せる

ホワイトバランス以外の修正で部分的な雰囲気をイメージに合わせる

2008年 04月 30日

gerry++

なんなんだっっっっ

2008年 04月 29日

Lightbox がどうとか

Lightbox って自分は結構便利なんだよなぁ。批判的な意見みたときびっくりしたぐらいだった (結構最近見ますね。増田で今日も見たからなんとなく書いてみたくなった)。

画像が大量にあるページで一個ずつ画像見るとき、戻って次っていう操作がかなり煩わしくて、Lightbox なしだと、

  1. 画像にマウスカーソルをあわせて中クリックで別タブで開く
  2. C-w で閉じる
  3. 次の画像をマウスカーソルで選んで……

をくりかえしたり、

  1. 普通に画面遷移させて同じタブでみる
  2. Backspace で戻る
  3. 次の画像をマウスカーソルで選んで……

をやったりするんだけど、これ、開く操作と閉じる操作・次の画像を見る操作、っていうのがいちいち違うので手の動きが増えてめんどうくさくて、あといちいち元のページが視界から消えてしまうので次の画像を選ぶとき毎回迷う……

でもって、まともに Lightbox が設定されたページだと、最初の一つをマウスでクリックして開けば、次の画像みるときワンクリックなりワンキーなので楽だなーって感じだなぁ。

あと、Lightbox が設定されていれば、Greasemonkey で表示方法とかこっちで変えて、一括で開くとか勝手にやりやすいので、(メタデータ普及的な意味で) 使われてる分にはもっとやれって感じだなー。(lightbox っていう名前がメタデータとしてどうなのとかは別にして)

2008年 04月 26日

日付っぽいもの全てに、現在からの相対時間を付与する

	var walker = document.createTreeWalker(
		document.body,
		NodeFilter.SHOW_TEXT,
		{
			acceptNode : function (node) {
				return NodeFilter.FILTER_ACCEPT;
			}
		},
		false
	);

	var hits = [];

	while (walker.nextNode()) {
		var node = walker.currentNode;
		var str  = walker.currentNode.nodeValue;
		var m    =  /(\d{4})-(\d\d)-(\d\d)|(\d+)年(\d+)月(\d+)日/.exec(str);
		if (m) {
			var time = new Date(
				+(m[1] || m[4]),
				+(m[2] || m[5]) - 1,
				+(m[3] || m[6])
			);

			hits.push({
				match: m,
				node: node,
				date: time
			});
		}
	}

	for (var i = 0, len = hits.length; i < len; i++) {
		var m    = hits[i].match;
		var node = hits[i].node;

		var surround = document.createElement("span");

		var range = document.createRange();
		range.setStart(node, m.index);
		range.setEnd(node, m.index + m[0].length);
		range.surroundContents(surround);

		var info = document.createElement("span");
		var style = info.style;
		style.position = "relative";
		style.top      = "-0.5em";
		style.fontSize = "80%";

		var diff = (new Date()).getTime() - hits[i].date.getTime();
		day = Math.floor(diff / 1000 / 60 / 60 / 24);
		info.appendChild(document.createTextNode("("+day+"日前)"));
		surround.appendChild(info);
	}

obsolete フラグ を見ていて、とりあえず相対時間表示がほしいなぁとおもったので userscript かいた。けど、なんか日本語が Greasemonkey でうまいことマッチしなくてめんどくなった……

TreeWalker で nextNode よんでるところと、実際 DOM を操作しているところを別にしているのは、DOM で子要素にまたマッチするノードを追加したりすると、nextNode() でそれがヒットしてっていう無限ループになるからです (なんか回避策あるのかな)。あとは普通に Range つくってるだけ…… クロスブラウザとか考えたらこんな簡単には書けないだろうなぁ

nextNode よぶ位置だけかえてワンパスにしてみた

	var walker = document.createTreeWalker(
		document.body,
		NodeFilter.SHOW_TEXT,
		{
			acceptNode : function (node) {
				return NodeFilter.FILTER_ACCEPT;
			}
		},
		false
	);

	var node = walker.nextNode();
	while (node) {
		var str  = node.nodeValue;
		var m    =  /(\d{4})-(\d\d)-(\d\d)|(\d+)年(\d+)月(\d+)日/.exec(str);
		var next = walker.nextNode();
		if (m) {
			var time = new Date(
				+(m[1] || m[4]),
				+(m[2] || m[5]) - 1,
				+(m[3] || m[6])
			);

			var surround = document.createElement("span");

			var range = document.createRange();
			range.setStart(node, m.index);
			range.setEnd(node, m.index + m[0].length);
			range.surroundContents(surround);


			var info = document.createElement("span");
			var style = info.style;
			style.position = "relative";
			style.top      = "-0.5em";
			style.fontSize = "80%";

			var diff = (new Date()).getTime() - time.getTime();
			day = Math.floor(diff / 1000 / 60 / 60 / 24);
			info.appendChild(document.createTextNode("("+day+"日前)"));
			surround.appendChild(info);
		}
		node = next;
	}

gerry++

2008年 04月 20日

Flickr の写真のヒストグラム表示

ヒストグラムみたいなーっておもって、どっかに画像なげるだけで表示してくれる API ないかなーっておもったけど、それっぽいのが見当らなかったので、つくった。

http://d.hatena.ne.jp/nitoyon/20071009/as3_histogram1 をまんまパクって、RGB それぞれ表示してるだけです。

Photoshop の RGB ヒストグラムはグレースケールじゃなくて平均?をとっているっぽいけど、フィルタ一発でどうやるのかわからなかったのでやめた。(あんまりみないし)

2008年 04月 13日

はてダでニコ動整理