2006年 01月 16日

Rhythmbox now playing

更新できずにいた now playing をどうにかする。

Rhythmbox にしてから now playing が更新できなかったんだけど、rbscrobbler を適当にハックして情報投げるようにしてみた。全く難しいことをやっていないんだけど、Python がまったくわからんおかげで、invalid syntax で何度も怒られた。

rbscrobbler.patch

UTF-8 で送られてくるので、CGI 側では特に変換をしないように変更。ていうかこの CGI 古いなぁ。クラスメソッド使うときは :: 使ってたころだ。

Brainfuck on Ruby

Brainfuck インタプリタ。

arr = []
ptr = 0
soc = ARGF.read
pos = 0
while soc.size > pos
print soc[pos].chr if $DEBUG
p arr if $DEBUG
arr[ptr] ||= 0
case soc[pos]
when ?>
ptr += 1
when ?<
ptr -= 1
when ?+
arr[ptr] += 1
when ?-
arr[ptr] -= 1
when ?.
print arr[ptr].chr
when ?,
arr[ptr] = $stdin.getc
when ?[
if arr[ptr].zero?
n = 1
while n.nonzero?
pos += 1
case soc[pos]
when ?[
n += 1
when ?]
n -= 1
end
end
end
when ?]
n = -1
while n.nonzero?
pos -= 1
case soc[pos]
when ?[
n += 1
when ?]
n -= 1
end
end
pos -= 1
end
pos += 1
end
puts

mailto:>++++++++++[<++++++++++>-]<-. +++++. +++++++. >++++++[<---------->-]<+. +. >++[<+++++>-]<+. >++++[<++++++++++>-]<++++. +++. ++++++++. -----. -------------. ----. +++++++++++. >++++++[<---------->-]<--. >++++++[<++++++++++>-]<++++. ---------. +++++++++++++++. 途中式 もっと短くしろよとかね。知らないよ。1パターンしか使ってないしね。いやでも別にね。ね。

bfi.rb Brainfuck の Ruby 実装 ってのを見つけた。変数名以外殆ど同じ(w. 最後に puts つけてるのまで同じだ。おもろいなぁ。ちなみに最後の puts は zsh 対策です。

The Ruby BrainFuck Interpreter クラス使ってる

アルゴリズム自体は Brainf*ck で頭にいれ、テストもそのページで紹介されているプログラムを使った。

2005年 12月 22日

昔はPHPが

昔 (といっても2-3年前) は PHP が好きだったんだよなぁ。なんでだろう。HTML に埋め込み、ウェブに特化してるってのがよかったんだろうか。

そういえば、そのころはデータベース使うのも特に抵抗がなかった。

とりあえず、少なくとも Ruby を知らなかったっていうのはある気がする。Perl は暗号で読めないし、PHP には一応日本語のリファレンスがちゃんとあったから、とっつきやすかったのかもしれない。

なんていったらいいかよくわからないんだけど、感覚としては Ruby は優しくかつ筋が通ってる感じ、Perl は玄人、PHP は楽ちんダサみたいな。いやでも比べるのが間違ってるんだろうなぁ。PHP ってなんかそこらへんの個人がやっつけで作ったマクロ言語っぽい臭いがするし。

とはいえ実用的っていえば実用的なのが PHP のキモさというかなんというか。ほげーっとしつつてきとーに書いても 500 が出にくいところがいいのかもしれない。

関係ないけど Ruby で CGI 書くときは一枚ラッパ書けるようにした。500 でるとこんなかんじになるように。#!/usr/local/bin/ruby /virtual/lowreal/bin/rubycgi.rb みたいな。ローカルは Windows だから関連付けで Apache どーん

なんか日本語書けない。もともと書けないけどさ。

プログラミングのテスト

次の式を評価せよとかいう問題で (-5 != -5) * 1.5 + 6 とかいうのがでた。実数の場合小数点以下二位まで書けとかいう問題。解答欄には 6 と書いたけど、今実行してみたら 6.00 だった。しらねぇよと。。0 なんて実数でも整数でもいいだから型変換しなくていいじゃん。とかいうと整数ならなんでもそうだろという話になるけど。

C 言語で評価せよなんて書いてなかったから素直に undefined method `*' for false:FalseClass と書けばよかった。解答欄が小さいのがいぢめだ。

2005年 12月 04日

ブラウザ上でコードを読もうとしても

ブラウザ上でコードを読もうとしても頭に入らない。

たとえばデザインパターンの例なんかをブラウザ上で見たりする機会は結構あるけど、そういうのってまったく頭に入ってこない。頭が理解しようとしない。

どんなコードでもそうかっていうと違う (Ruby のリファレンスのサンプルコードは頭に入る) んだけど、なんでだろう。なんかただたんにコードの長さと必要性の問題な気がしてきた。

2005年 12月 02日

ECMAScript での var

前に書いた気がするけど、ECMAScript の var は Io の setSlot に似ている。

var foo; と書くと、既存のスコープの変数オブジェクトのプロパティに foo が作られる。そして foo = "1"; を書くと、スコープチェインの最初に、作られた foo プロパティを発見するため、そこに代入される。

一方 foo = "1";var 無しにいきなり書いた場合、スコープチェインの末 Global オブジェクトにいきつき Global オブジェクトのプロパティに新たに勝手に foo が作られて代入される。

// Global Code の開始
// Scope Chain: [Global]
// Variable Object: Global
//----
// Variable Object (Global)
// のプロパティ foo に "foo" が代入される。
var foo = "foo";
// 上に同じ
var bar = "bar";
function foobar() {
// Function Code の開始
// 新たに Activation Object (=このコンテキストでのVariable Object) が作られる。
//   (このとき arguments プロパティが自動的にセットされる。)
// Scope Chain: [foobarActivationObj, Global]
//     foobarActivationObj は仮の名前で実際にはアクセスできない。
// Variable Object: foobarActivationObj
// Variable Object (foobarActivationObj)
// のプロパティ foo に "fbfb" が代入される。
var foo = "fbfb";
// Identifier があると Scope Chain を辿る。
// この場合最初の foobarActivationObj に foo を発見できる。
foo = "bfbf";
// この場合最初の foobarActivationObj に bar を発見できないため
// Scope Chain を辿り、Global で bar を発見する。
bar = "bzbz";
// この場合 Scope Chain をたどって、Global に行き着いても発見できないため
// 勝手に Global に baz プロパティを作る。
baz = "baz";
baz.foo = "foo";
with (baz) {
// with は Scope Chain の先頭に
// 指定オブジェクトを突っ込む
// Scope Chain : [baz, foobarActivationObj, Global]
foo = "bar";
// Variable Object は変わらない
var f = "!!!";
}
baz.foo; //=> "bar"
baz.f //=> undefined
f; //=> "!!!"
}
foobar();
foo; //=> "foo" 最初にグローバルで代入したまま
bar; //=> "bzbz" 書き換えられている
baz; //=> "baz" グローバルで一切でてきていないのに存在する

Io の場合 = (updateSlot) はスコープチェインに Identifier を発見できない場合例外が発生する。現在の変数オブジェクトのスロットに突っ込むときは := (setSlot) を使用する。Io は明確な決まりがあるんだけど、ECMAScript は曖昧。気が付くと Global オブジェクトにプロパティがだらだらできたりする。

微妙にわかりにくいのは、Global Code においての Variable Object が Global で、変数に this.foo というようにアクセスできるのに対し、Function Code の Variable Object には一切触れないこと

ときどき関数中で var a = b = c = 0; って書いているのを見かけるけど、この場合の b, c は Global オブジェクトのプロパティ (または途中であるならその変数オブジェクトのプロパティ) になる。var a, b, c; a = b = c = 0; とか書くのが正解。

Prototype Chain もそうだけど、「見えないオブジェクト」がいくつかあってなかなか怖い。

2005年 11月 28日

UI -> 機能

先に UI 作ったほうがやる気が出る。さきに機能を実装すると UI 作るのが面倒くさくなって UI がおろそかになる。そして UI が悪いものはいくら内部実装がかっこよくても使わない。

2005年 10月 18日

Ruby's eash on ECMAScript

ECMAScript でイテレータ なんてのを書いたことがあったけど、これ、each の中で break ができないのでちょっと気持ち悪い。ちまたで時々聞く ruby.js はどうやって解決しているんだろう?って思ってみてみたけど、特に何もしてなかった。つーか ruby.js 見つけるのが割りとめんどかったよ。

いろいろ考えたけどとりあえず動いたのをメモっとく。

function Array_each(func) {
try {
var context = {
escape : function () {
throw "break";
}
}
for (var i = 0, len = this.length; i < len; i++) {
func.apply(context, [this[i]]);
}
} catch (e) {
if (e != "break") throw e;
}
return this;
}
Array.prototype.each = Array_each;
[1, 2, 3].each(function (i) {
if (i > 1) this.escape();
Debug.dump(this);
});

Function.prototype.apply() の第一引数は関数の中での this なのでそれにメソッド設定してみる。ループから抜けるのに try - catch。投げるオブジェクトは "break" という文字列。"break" 以外の場合は例外を投げなおす。

ほんとはコンテキストの変数オブジェクトに直接関数を突っ込めるのがいいんだけど、ECMAScript では変数オブジェクトにアクセス方法はない (Activation オブジェクトは変数の実体化を目的とした変数オブジェクトとして使用される。Activation オブジェクトは純粋に仕様のメカニズムである。 Activation オブジェクトへのアクセスは ECMAScript プログラムには不可能である。 メンバ (変数) にはもちろんアクセスできるから eval つかえばいいけどスマートとは思えない。) のでこんな感じ。Global (window) は使いたくないし……

あとは eval(func.toString().replace(/\{/, "\{ var escape = function () { .. };")) とか?

2005年 10月 15日

Io and Ruby

最近 Ruby 関連を経由して Io language を見ることが多くてなんかうれしい。別に Io 使ってるわけじゃないんだけど、好きだから。

2005年 10月 08日

for の括弧の中での演算子

俺は演算子の前後にスペースを入れない書き方が大嫌いなんだけど、for の括弧の中では例外的にスペースを入れないようにしていた時期があった。なんとなくまとまりのあるほうがいいかなぁって思っていたから。

でも最近 Javascript で var をちゃんと使うようにしてからはその変則的なルールをやめた。

for (var i=0; i<100; i++)
alert("pgr");
for (var i = 0; i < 100; i++)
alert("pgr");

var の後にはスペースがもちろん必須なわけで、そのあとに続く部分でスペースを空けないと var だけが浮いてしまう感じに見える。気持ち悪いのでスペースをあけるようにした。var とかない C でもスペースをあける。ほとんど同じ文法なのにスペースあける場所が違うとかは論外だからね。