2008/08/01

就職しました。

ポスト @ 23:36:21 |     

2008年8月1日に、都内のベンチャーに就職しました。
長いこと(2年くらい ?) PHP から遠ざかっていましたが、また PHP 界隈に復帰します。
よろしくお願いします。

2008/07/31

ニートになりました。

ポスト @ 18:34:34 |     

報告(誰に?)が送れましたが
2008年6月30日付けでサラリーマンを辞め、ニートの仲間入りしました。
一人前のニートになるべく頑張ります。よろしくお願いします。

2008/07/26

Log4Io を作ってみた。

ポスト @ 20:52:56 |     

Log4Io を作ってみた。
ref http://coderepos.org/share/browser/lang/io/Log4Io/io

使い方は、Log4** とほぼ同じで、こんな感じ

Log4Io

logger := Log4Io getLogger("sample")
logger addAppender(Log4Io ConsoleAppender with)
logger setLevel(Log4Io Level INFO)
if(logger isDebugEnabled) then (
    logger debug("debug")
)
if(logger isInfoEnabled) then (
    logger info("info")
)
if(logger isWarnEnabled) then (
    logger warn("warn")
)

これを実行するとこんな感じ。

==> 2008-07-26 20:48:50 JST INFO sample - info
==> 2008-07-26 20:48:50 JST WARN sample - warn

また、Lobby に log4ioLogger を設置しているので、こちらはそのまま使えます。

Log4Io

// lobby log4ioLogger
log4ioLogger error("hoge")
log4ioLogger info("foo")
log4ioLogger warn("bar")

こっちは、こんな感じに出力される

==> 2008-07-26 20:48:50 JST ERROR Log4Io - hoge
==> 2008-07-26 20:48:50 JST INFO Log4Io - foo
==> 2008-07-26 20:48:50 JST WARN Log4Io - bar

ほとんど log4js からパクったけど、Log4J 並みの細かいことも作れそう。
ただ、パッケージとかが無い分だけ色々と面倒なのだけど。。。

Io の clone でハマる

ポスト @ 20:42:29 | ,     

clone したときは、init メソッドが呼ばれて、そこで必ず初期化しないとダメだということ
以下のコードだと、オブジェクトの値が clone されるんだね

Hoge := Object clone do(
    values := List clone
    with := method(name,
        c := self clone
        c values append(name)
        c
    )
)

a := Hoge with("a")
b := Hoge with("b")
a values println
==> list(a, b)

これってつまり js だと、以下のコードと同じってことか。

var Hoge = function (){};
Hoge.prototype = {
    values: [],
    with: function(name){
        var c = new Hoge
            c.values.push(name)
        return c
    }
};

var a = Hoge.prototype.with("a")
var b = Hoge.prototype.with("b")
print(a.values)
==> (a, b)

ということで、Io のコード及び、js のコードを直すなら、こんな感じになる。
# って基礎中の基礎か

Io

Hoge := Object clone do(
    init := method(
        self values := List clone
    )
    with := method(name,
        c := self clone
        c values append(name)
        c
    )
)

a := Hoge with("a")
b := Hoge with("b")
a values println
==> a
b values println
==> b

js

var Hoge = function (){return this.init.apply(this)};
Hoge.prototype = {
    init: function (){
        this.values = []
    },
    with: function(name){
        var c = new Hoge
            c.values.push(name)
        return c
    }
};

var a = Hoge.prototype.with("a")
var b = Hoge.prototype.with("b")
alert(a.values)
==> a
alert(b.values)
==> b

慣れは怖い

2008/07/25

メモリを4GBに増設した

ポスト @ 20:16:15 | ,     

増設したといっても、結構前に増設してたんだけど、メモリが 1GB から 4GB になると結構快適に過ごせてます。
購入は上海問屋 → 【楽天市場】[送料\210〜]【相性保証付】[個数限定特価] ノートパソコン用メモリ DDR2 PC2-5300 2GB:上海問屋セレクト SODIMM DDR2 PC2-5300 2GB [メ1]:上海問屋
安いっすね。もっと早くに買っておけば良かった。

2008/07/23

Io で curry, bind を実装する

ポスト @ 23:07:53 | ,     

prototype.js の Function.prototype.curryFunction.prototype.bind が Io にも欲しくなったので、簡単に実装してみた。

ちなみに、Function.prototype.curry は引数のカリー化を行ってくれる関数プロトタイプで、Function.prototype.bind は、スコープのカリー化もしてくれるヤツ(って説明でいいのかな)

Block apply := method(target, args,
    args = if(args isNil, list(), args)
    target = if(target isNil, scope, target)
    self setScope(target)
    self performWithArgList("call", args)
)
Block bind := method(
    args := call message argsEvaluatedIn(call sender)
    target := args at(0)
    args = args slice(1)
    b := self
    return block(
        b apply(target, args union(call message argsEvaluatedIn(call sender)))
    )
)
Block curry := method(
    args := call message argsEvaluatedIn(call sender)
    if(args size < 1) then (
        return self
    )
    /*
    target := args at(0)
    args = args slice(1)
    */
    b := self
    return block(
        b apply(scope, args union(call message argsEvaluatedIn(call sender)))
    )
)

まぁ、bindもcurryも同じようなものなので、こんな感じで動かす。

hoge := Object clone do(
    message := "this is hoge"
)
foo := Object clone do(
    message := "this is foo"
)

promp := block(a, b,
    "#{self message} at #{a}, #{b}" asMutable interpolate println
)

promp setScope(hoge)
a := promp curry("aaa")
a call("bbb")
==> this is hoge at aaa, bbb

b := promp bind(foo, "ccc")
b call("ddd")
==> this is foo at ccc, ddd

使い道は、これから考える

2008/07/20

translate posts of io mailing list

ポスト @ 1:02:45 , 修正 @ 2008/07/20 1:13:37 |     

io のメーリングリストを 超 オレオレ 訳にして、英語を読む。
via - Found something but I don't know what to make of it

[Io] Found something but I don't know what to make of it
何かみつけたんだけど、よくわからないんだ。

So I was in the process of compiling all the libs for the addons and
poking around looking for some info when I ran into a site in a
language I can only guess is Chinese:

アドオンのライブラリをコンパイルする方法とかの情報を探し回っていたら、
サイトに出くわしたんだけど、どうやら言語は中国語っぽいんだよね。

http://blog.xole.net/category.php?k=ioLanguage

Seems to be lots of Io code but I can't decipher all of what it does.
Is this a translation of existing info? Anyone know?

たくさんの io のコードがあるように思えるんだけど、それが何に関して書かれているか読めない(decipher: 解読?)んだよね。
ここに書かれているのは、何か既存の情報の翻訳なの?誰か知ってる?

投稿者C. Olson さんは、どうやら僕のところに漂着してしまったみたいだけど、中国語っぽくて読めなかったらしい。
んで、Brian さんが次の投稿で

Re: [Io] Found something but I don't know what to make of it

> So I was in the process of compiling all the libs for the addons and
> poking around looking for some info when I ran into a site in a
> language I can only guess is Chinese:
>

Japanese actually.
日本語みたいだね。

> http://blog.xole.net/category.php?k=ioLanguage
>
> Seems to be lots of Io code but I can't decipher all of what it does.
> Is this a translation of existing info? Anyone know?

Doesn't look like stuff I recognize from other posts so I imagine this
user has been doing their own investigation. The GC write up is quite
interesting (relating to tweaking the incremental step used in
collection).

うーん、どうやらそういった情報(ここでは「translation of existing info: 既存の情報の翻訳」かな)では無いみたいだよ。他の記事から私が想像するに、それらの記事は、それについて調査したことを書かれているんだと、私は思うな。
GC について書き上げているのはかなり面白いと思う(GC の収集には、増加ステップ(incremental step)の調整に関係しているってさ)

Brian さんは日本語が読めるらしい。しかも他の記事から読み解くとかスゲー人なんだな。
GC についても触れてくれてるのも嬉しい :)
そして、Steve Dekorte さんからの投稿

Re: [Io] Found something but I don't know what to make of it

> So I was in the process of compiling all the libs for the addons and
> poking around looking for some info when I ran into a site in a
> language I can only guess is Chinese:
>
> http://blog.xole.net/category.php?k=ioLanguage
>
> Seems to be lots of Io code but I can't decipher all of what it does.
> Is this a translation of existing info? Anyone know?

Here's a translation, but I'm still not very clear:
翻訳してみた。でもまだ明確にはならないなあ:

http://209.85.171.104/translate_c?hl=en&sl=ja&tl=en&u=http://blog.xole.net/category.php%3Fk%3DioLanguage&usg=ALkJrhjVqXbSXGowxw8i2ZyTgQC-b85dUA

うーん、皆さんを困らしているみたいですが、私も困惑。
だって英語できないんだもん。オレオレ訳が正しいとも限らないしなぁ。

ちなみに、"translation of existing info" については、これらかな。

今回出てきた英語

話し言葉(?)みたいな英語が多くて、意訳しかできないけど、こんな感じかな

Found something ...
なんかみつけた。
チョーそのまま。Found は find の過去形だからこんな感じかなぁ
make of it
理解する(?)
make of ... っていろんな意味があってよく分からん。英英辞典曰く(to understand or meaning character of...)
ref - GetUpEnglish: WHAT DO YOU MAKE OF IT?
poke around...
探し回る(?)
run into(ran into)...
...に偶然に会う
話し言葉っぽい感じ。英英辞典曰く(to meet by chance)
Seems to be...
...のようだ(appears to beににてる)
Seems to be... で開始されてもいいんだね。文法とかあんまり気にしなくてもいいんだ。
look like stuff...
...のように見える(かな?)
seems とか looks like はなんだ。結構曖昧なの?
ref - seems like, look likeの使い方を詳しく説明して欲しいです。それと going to be... - Yahoo!知恵袋, seem to be と It seems that の違い - 教えて!goo

話し言葉っぽいのが多くて、their own の their はどれだよ。ってのが多いなあ。うーん、難しい。

2008/07/16

買い物しようと街まで出かけたら?

ポスト @ 0:46:06 |     

以前、現場で話題になったヤツをアバウトミーで作ってみた。
質問 : 買い物しようと街まで出かけたら? : アバウトミー : @nifty

ドライブ派とかは年齢バレるっつーの

2008/07/14

io で GC を見る

ポスト @ 2:58:44 , 修正 @ 2008/07/14 3:16:07 | , ,     

io の Collector を使って、GCの動きを少し見てみる
via - Io の make test(libs/iovm/tests/run.io)

コードとしては、こんな感じのを使うらしい。

writeln("mpa \t as \t mb \t time \t mbt \t gc")

lastTimeUsed := 0.0

list(1.01, 1.05, 1.1, 1.2, 1.5, 1.7, 2, 4) foreach(as,
    list(0.01, 0.1, 1, 2, 4, 16) foreach(mpa,
        Collector setMarksPerAlloc(mpa)
        Collector setAllocatedStep(as)
        
        time := Date clone cpuSecondsToRun(test)
        mb := (Collector maxAllocatedBytes / 1000000) asString(0, 2)
        
        writeln(
            Collector marksPerAlloc asString(0, 2), "\t",
            Collector allocatedStep asString(0, 2), "\t",
            mb, "\t", 
            time asString(0, 2) , "\t", 
            (mb asNumber * time) asString(0, 2), "\t", 
            (100 * (Collector timeUsed - lastTimeUsed) / time) asString(2, 1), "%"
        )
        
        lastTimeUsed = Collector timeUsed

        // Collector showStats
        writeln("collected items: ", Collector collect)
        Collector resetMaxAllocatedBytes
    )
    "" println
)

今回は、循環参照するようにしてそれの GC を取ってみます。

aaa := method(
    Hoge := Object clone do(
        foo ::= nil
    )
    Foo := Object clone do(
        hoge ::= nil
    )

    h := Hoge clone setFoo(Foo clone setHoge(Hoge clone))
    f := Foo clone setHoge(Hoge clone setFoo(Foo clone))
    h clone setFoo(f clone setHoge(h clone))
    f clone setHoge(h clone setFoo(f clone))

    l := List clone
    for(i, 0, 100, l append(h, f, i * 0.987654321))
)

以下、全体

// Collector setDebug(true)
aaa := method(
    Hoge := Object clone do(
        foo ::= nil
    )
    Foo := Object clone do(
        hoge ::= nil
    )

    h := Hoge clone setFoo(Foo clone setHoge(Hoge clone))
    f := Foo clone setHoge(Hoge clone setFoo(Foo clone))
    h clone setFoo(f clone setHoge(h clone))
    f clone setHoge(h clone setFoo(f clone))

    l := List clone
    for(i, 0, 100, l append(h, f, i * 0.987654321))
)
test := method(1000 repeat(aaa))

writeln("time: ", Date clone cpuSecondsToRun(test), " seconds")

writeln("mpa \t as \t mb \t time \t mbt \t gc")

lastTimeUsed := 0.0

list(1.01, 1.05, 1.1, 1.2, 1.5, 1.7, 2, 4) foreach(as,
    list(0.01, 0.1, 1, 2, 4, 16) foreach(mpa,
        Collector setMarksPerAlloc(mpa)
        Collector setAllocatedStep(as)
        
        time := Date clone cpuSecondsToRun(test)
        mb := (Collector maxAllocatedBytes / 1000000) asString(0, 2)
        
        writeln(
            Collector marksPerAlloc asString(0, 2), "\t",
            Collector allocatedStep asString(0, 2), "\t",
            mb, "\t", 
            time asString(0, 2) , "\t", 
            (mb asNumber * time) asString(0, 2), "\t", 
            (100 * (Collector timeUsed - lastTimeUsed) / time) asString(2, 1), "%"
        )
        
        lastTimeUsed = Collector timeUsed

        // Collector showStats
        writeln("collected items: ", Collector collect)
        Collector resetMaxAllocatedBytes
    )
    "" println
)

これを実行すると、以下な感じの出力になる。

time: 0.511943 seconds
mpa 	 as 	 mb 	 time 	 mbt 	 gc
0.01	1.01	0.00	1.62	0.00	0.0%
collected items: 2
0.10	1.01	0.00	1.65	0.00	0.0%
collected items: 183
1.00	1.01	0.00	1.68	0.00	0.0%
collected items: 182
2.00	1.01	0.00	1.68	0.00	0.0%
collected items: 182
4.00	1.01	0.00	1.69	0.00	0.0%
collected items: 182
16.00	1.01	0.00	1.73	0.00	0.0%
collected items: 182

:
:
:

0.01	2.00	0.00	0.40	0.00	0.0%
collected items: 4879
0.10	2.00	0.00	0.40	0.00	0.0%
collected items: 2155
1.00	2.00	0.00	0.35	0.00	0.0%
collected items: 57131
2.00	2.00	0.00	0.35	0.00	0.0%
collected items: 64649
4.00	2.00	0.00	0.34	0.00	0.0%
collected items: 68050
16.00	2.00	0.00	0.35	0.00	0.0%
collected items: 70914

0.01	4.00	0.00	0.38	0.00	0.0%
collected items: 22421
0.10	4.00	0.00	0.40	0.00	0.0%
collected items: 2373
1.00	4.00	0.00	0.32	0.00	0.0%
collected items: 141619
2.00	4.00	0.00	0.31	0.00	0.0%
collected items: 145915
4.00	4.00	0.00	0.38	0.00	0.0%
collected items: 1119
16.00	4.00	0.00	0.38	0.00	0.0%
collected items: 2878

なぜか、Collector timeUsed の時間が取得できない...
今度調べる。

ちなみに、Collector setDebug(true) で実行すると、GC が sweep していく様子が見れます。

Collector_sweepPhase()
  allocated 9951
  allocatedSweepLevel 9938
Collector_sweepPhase()
  allocated 9892
  allocatedSweepLevel 9891
Collector_sweepPhase()
  allocated 9965
  allocatedSweepLevel 9964
Collector_sweepPhase()
  allocated 9892
  allocatedSweepLevel 9891
Collector_sweepPhase()
  allocated 9979
  allocatedSweepLevel 9978
Collector_sweepPhase()
  allocated 9899
  allocatedSweepLevel 9898
Collector_sweepPhase()
  allocated 9994
  allocatedSweepLevel 9993
Collector_sweepPhase()
  allocated 9910
  allocatedSweepLevel 9909
Collector_sweepPhase()
  allocated 9871
  allocatedSweepLevel 9870

データ推移

んで、これで終わりではなくて、すこしデータ推移も眺めてみた。
ちなみに、as は Collector allocatedStep で、mpa は Collector marksPerAllocとなっています。

各、as と mpa の意味として

the allocatedStep (can have a fractional component, but must be larger than 1). A collector sweep is forced when the number of allocated objects exceeds the allocatedSweepLevel. After a sweep, the allocatedSweepLevel is set to the allocated object count times the allocatedStep. Returns self
the number of incremental collector marks per object allocation (can be fractional). Returns self.

ということで、as: 1.05, 1.10, 1.20, 1.50, 1.70, 2.00, 4.00 のデータを抜粋
また、x 軸はmpa(marksPerAlloc)値、y 軸は回収されたオブジェクトの個数となっています。







ここから分かることは、as(allocatedStep) の値が小さい場合は、mpa(marksPerAlloc)の値が大きい方が 回収されるオブジェクトの個数が多いらしい。
しかし、as の値が大きくなるにつれて、mpa の値が小さい方が回収されやすくなっている。

これが、いわゆる GC 最適化って言われてるヤツかな。

他にも、as値が小さく、mpa値が大きいと GC にかかる時間が多いらしい(これはたまたまなのかもしれないけど)

また、回収された個数でみてみると、as値とmpa値が両方大きいからといって回収されるオブジェクトの個数が増えるというわけでは無いようだ。

as:1.10の時

as: 1.50の時

as: 2.00の時

as: 4.00の時

ってことで、簡単なまとめ

as(allocatedStep) 値は、回収されるオブジェクトの個数に比例する
mpa(marksPerAlloc) 値は、as 値が小さい時に、回収されるオブジェクトの個数を増やすことができるが、as 値が大きくなると、回収効率は見込めない。
as 値が小さい場合は、GC に時間がかかる場合が多いが、as 値はある一定以上になる場合は、GC の時間に比例しなくなる。

ということで、やっぱり↓の画像のとおりになりそう。

簡単なデータしか取ってないけど、Numbers から PDF に出力したモノを置いておきます。
http://blog.xole.net/resources/io_collector_low.pdf

2008/07/09

io で GoogleChart

ポスト @ 5:01:08 , 修正 @ 2008/07/09 5:06:32 |     

io languageでGoogleChartのURLデータを出力するヤツを作ってみた。
ref - http://xole.net/googlechart/sample.io

上のサンプルにもあるように、こんな画像を出力できるようにしただけ。

# 画像処理とかやってないのが、ヘタれ

こんなコードを書きます。

#!/usr/local/bin/io
doFile("GoogleChart.io")
doFile("Types.io")
doFile("Labels.io")
doFile("Colors.io")
doFile("Data.io")
doFile("Styles.io")

types := Types clone
types PieChart p3

labels := Labels clone
labels Title chtt(
"""
    GoogleChart sample
    by Io WebAPI
""")

labels Label chl("hoge", "foo", "bar")

data := Data clone
data Text chd("60", "30", "10")

styles := Styles clone
styles size(320, 200)

chart := GoogleChart URL withQuery(types, labels, data, styles)

"Content-type: text/html" println
"""
<html>
    <head>
        <title>GoogleChart with Io</title>
    </head>
    <body>
        <p>#{chart asHTML}<br />generated on #{Date}</p>
    </body>
</html>
""" interpolate println
exit

もう少しまともなヤツにしようと考えてる(もう少し表計算チックにできれば綺麗だよね)けど、とりあえずこれで。
コードはcodereposにあげました。
ref - http://coderepos.org/share/browser/lang/io/WebAPI/GoogleChart

以前のログ