2007-12-26
■ [reposh] プロンプトにsystem_nameを入れたいとしたら
結構、いろんな反応があって驚いているReposhですが。
- eval方式 - prompt: "#{@system_name} >"
- erb方式 - prompt: <%=@system_name%> >"
- DSL方式 - prompt: {system_name} >
ということで、適当に「{system_name}と書くとシステム名に置き換わるよ」とかのルールを決めるのが良いかなぁと 思いました。DSLというほどのもんじゃないですけど。
monotoneは、そういえば、名前は聞いたことあるような…。
結構たくさんあるんですね。
■ [biwascheme] 命令群を列にしよう - Scheme VM を書く - ひげぽん OSとか作っちゃうかMona-
あー、単にペアからベクタにするって話じゃなくて、再帰的な構造を止めるって話だったのですね。
確かに、クロージャを普通にシリアライズしたらif文以降が重複しますよねぇ。気付いてなかった(笑)。
例:
(begin (if #t 1 2) (display "hoge"))
これをコンパイルすると以下のようになる。(メモリ上は共有されてるんだけど、こうやって出力すると重複してしまう)
[constant true [test [constant 1 [frame [constant 'hoge' [argument [refer-global 'display' [apply 1]]]] [halt]]] [constant 2 [frame [constant 'hoge' [argument [refer-global 'display' [apply 1]]]] [halt]]]]]
moshではLOCAL_JMPという命令を増やすなどしてこれを解決するとのこと。アセンブラっぽいな。
biwaschemeにはまだ大きなサンプルコードがないので実行速度が問題になってないけど、いずれは考えないといけないのかな。
■ [biwascheme] arguments.callee.callerを使ってエラーメッセージの表示を簡素化してみた
BiwaSchemeではassert_*という関数を使って型チェックをしている。
define_libfunc("abs", 1, 1, function(ar){ var n = ar[0]; assert_number(ar[0]); return (n<0 ? -n : n); });
なので、例えば (abs "hoge") のような式を評価すると
Error: abs: number required, but got "hoge"
というエラーになる。
ここで注目してほしいのがエラーメッセージに関数名が表示されている点で、以前はこれを実現するために
assert_number(ar[0], "abs");
とか関数名をいちいち書いていたのだけど、assert_* の側で arguments.callee.caller を使って 呼び出し元オブジェクトを参照することで*1、よりDRYな書き方ができるようになった。
callerは便利ですね。
ただ、Operaにはarguments.callee.callerがないんで関数名が表示できないんだけど…。デバッグの時はOpera以外を使ってくださいということで。
*1 define_libfuncで、関数オブジェクトのfnameというプロパティに関数名を設定している
■ [prog] コード読み
昨日、るりまのパッケージ版で概要でなく全文が表示されてしまうバグがあって、 某lingrチャネルをデバッグのメモ代わりに使わせてもらった(ごめんなさいw)。
せっかくなので記録として以下に貼り付けておく。
8:06pm (December 25)
template/library-indexがrhtmlらしい <td class="description"><%= compile_rd(lib.synopsis_source) %></td> でsynopsisじゃなく全体が表示されるのが問題 LiveReading
8:09pm (December 25)
libは@db.libraries.sortからとってきてる
8:10pm (December 25)
db = BitClust::Database.new(dbpath)
8:11pm (December 25)
@db.librariesは@db.librarymap().valuesとおなじ てか@librariesがなくて@dirty_librariesしかなくて dirtyの定義について全くコメントがないwww
librarymapはload_extent(LibraryEntry)でよみこむ
8:14pm (December 25)
Entryというクラスが各記事(エントリ)を表すのだと想像 extentってなんだろうなぁ
8:18pm (December 25)
load_extent -> id_extent -> entries(:library.to_s) みたいな流れらしい entriesの中でDir.entriesを読んでファイルパスをごりごり
8:20pm (December 25)
えっと、librarymap().valuesだからハッシュの値の方全部で それぞれはLibraryEntry.new(db, id)みたいなの
8:22pm (December 25)
idはdecodeid(path) メソッドをたどるスタックが深すぎて俺の脳容量はとっくに0よ
8:23pm (December 25)
ujihisa
確かに人間はすぐStackOverflowするよね 図示すれば一気に楽勝
yhara
decodeidはファイル名の-a-b-cをABCになおすらしい
hakobe
人間の脳のスタックはすごいちっさくて6個とかでもかなりすごい人とか聞いた
yhara
つまりidはString つまりlibrariesはLibraryEntry.new(db, "yaml")とかの配列らしいとわかった。 library-index <- screen.rb <- requesthandler.rb <- (以下略 @entries :: [LibraryEntry] (Haskell風)
8:29pm (December 25)
compile_rd(lib.synopsis_source) なわけだが synopsis_sourceの定義がsource().split(/\n\n/, 2).first || '' で この\n\nがじつにあやしいwwwうえwww
windows上でデータベースを作ると改行がCRLFになってて、それをunixに持っていくとうまくsplitできなくて 全文が表示されてしまう、というバグだったらしい。windows上でもopen(fname,"wb")で書き出すことで 解決した模様。
分かったこと:
- 変数の型がさっぱり分からなくて困った。
- これからは型が分かりやすいネーミングをするように注意しよう、と自戒
- メソッドコールのネストがすげー深くて難しかった。
- けっこう大規模なシステムだからしょうがないのかなぁ。