トップ «前の日記(2007-12-25) 最新 次の日記(2007-12-29)» 編集

Route 477



2007-12-26

[reposh] プロンプトにsystem_nameを入れたいとしたら

結構、いろんな反応があって驚いているReposhですが。

  1. eval方式 - prompt: "#{@system_name} >"
  2. erb方式 - prompt: <%=@system_name%> >"
  3. 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")で書き出すことで 解決した模様。

分かったこと:

  • 変数の型がさっぱり分からなくて困った。
    • これからは型が分かりやすいネーミングをするように注意しよう、と自戒
  • メソッドコールのネストがすげー深くて難しかった。
    • けっこう大規模なシステムだからしょうがないのかなぁ。