Ruby版Parsec

ふと何気にrubyとparsecで検索掛けてみたらありましたよ!!
rubygemsに登録されてるので

gem install rparsec

とするのみ。
日本語での導入としては立川さんの
http://akimichi.homeunix.net/~emile/aki/hiki.cgi?rparsec
http://akimichi.homeunix.net/~emile/aki/hiki.cgi?RubyistKyushu
が唯一な感じですが、丁寧に書かれていて分かりやすいです。
RubyistKyushuで紹介されてたようで。。むーむー。現地に行けないまでも情報はチェックしとくべきでした。

使ってみた感じでは少し癖はあるものの、パフォーマンス的にはそれなりに出ているようです。
とりあえずはパーサコンビネータ自体にそんな慣れていないので、怪しい言語仕様を実装してみて練習中です。現在、三項演算子をどう記述すればいいか悩んでみたり・・・左再帰がそのまま書けないってなかなか難しい。

玄箱 そして Macへ

これまで、個人的にfetchmail&imapd,pukiwiki,svn,sound outputのサーバーとして活躍していた玄箱のHDDがI/O error多発でもうお亡くなり寸前になってしまいました。どうも温度的にヤバい状態でうごいてるっぽいし、HDD換装はそれしてからとsetupの時間、そしてシリアルコンソールがないとトラブル時の処理が適当にしかできない(とりあえず電源切断して再起動とか:-)事からサーバー新設計画を発動
デスクトップPCは本体の置き場所に困るのとディスプレイの置き場所にも困るという2重の空間的制約のため却下し、ノートPC、それもついにMAC購入〜
まぁノーマルなMacBookなんですが、Macですよ!Mac OSX 素晴らしい。Finderのカラム表示やXCodeのInterfaceBuilder,/mach_kernelのあたりにNeXTの香りがほのかにしてそれだけでウキウキしてしまう。久々にObjective-C触っちゃおうかななんて思ってみちゃったり。
Macは初めてなので、アプリケーションとか全然わからず色々戸惑っている事も多いんですが、Windowsでは感じた事がないハードウェアとOSとの一体感があるように感じた。目新しさもあるんだろうけど、これからいじり倒した後自分がMacにどういう感想を持つのか楽しみ

と、この文章も慣れない「ことえり」で初日記書き

IntegerClass その後

結局、Integerから派生させるのは諦めて、普通にClassをつくり従来のInstanceMethodをほぼ全て(__id__,__send__,inspect以外)消してmethod_missingでto_s以外、全て内部で保持してるIntegerInstanceに渡す事にした。
こんなのいいのかなぁとか思いながら・・・
しかし、enum_instance.kind_of?(Integer)はtrueなのにInteger===enum_instanceはfalseになってしまっていて、これではcase文で嘘っぱちIntegerなのがばれてしまう。。。

self === obj


このメソッドは主に case 文での比較に用いられます。
objself と Object#kind_of?の関係がある時、真になります。つまり、case ではクラス、モジュールの所属関係をチェックすることになります。

しばらくコレをみて何でだおかしいよーと思ってたんですが、Rubyのソースをみててようやく気づいた。Object#kind_of?とは本当にObjectクラスで定義されたkind_ofだと。しかも後付けでdef Object.kind_of? とやっても駄目ですorz
要はCで書かれたソースの中でModule#===からrb_call系を使わず、つまりrubyフレームワーク(?)を使わずに直接Object#kind_of?のコードを呼び出してるんで、いくらClassでkind_of?メソッドを定義しても無駄のようです。
気になってリファレンスマニュアルとソースを見比べてたんですがObject#hogehogeをとか明記してある場合は、そういう事みたいで、ruby側で適宜Overwriteしたのが使われる場合はちゃんと「クラスで定義されている場合は」みたいな記述になってる(全部は到底チェックしてませんが。)。。。

今まで気づかなかった!!

で結局Module#===を再定義してもよくわからないけどだめで、Integer#===を再定義する事にして、どんどん気持ちの悪いコードを生産する事になったのでした。TT

IntegerClass

Integerの子クラスとして列挙型を作ろうとしたら、newがないとかallocatorがないとかいわれてしまった。
むーーん。どうすればいいのかな。Interger===enum_instanceがtrueになってほしいのだけれど。整数って難しいですね。。。

Ruby/DL2のIOまわりが・・・

セグってます。。。最新にしてみてもだめだった。IOをFILE*に変換してるあたりでしくってるんだろうか。
ただhttp://www.garbagecollect.jp/ruby/mswin32/ja/から貰ってきた1.8.5p2にhttp://rubyforge.org/projects/ruby-dl2/の0.6を入れたバージョンだとちゃんと動いてるので、もしかしたらコンパイル環境が悪いのかも?
どなたか情報持ってたら教えてください。

>type test.rb
require 'dl/import'
module A
  extend DL::Importer
  dlload "msvcrt.dll"
  extern "int printf(char*)"
  extern "int fprintf(FILE*,char*)"
  printf("hello world!\n")
  fprintf($stdout,"hello world2!\n")
end
>ruby test.rb
hello world!
C:/soft/ruby/lib/ruby/1.9/dl/func.rb:31: [BUG] Segmentation fault
ruby 1.9.0 (2006-12-05) [i386-mswin32_80]


This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Ruby/DL2 Tips

すでにDL1を忘れそうになってるけどメモ。

まずDL1からDL2への移行Tips

  • DL::Import -> DL::Importer
  • r,rs = hogehoge() -> r = hogehoge()

rsの部分は直接hogehogeの引数の内容が変わるようになる(Pointer相当部分)。これによりstrcatとかの場合にchar *buffはこちらで確保したサイズが維持されるので\0以下を明示的に削除したりする処理が付け加わる。

次 structについて

  • 構造体をメンバーとして持つ構造体は未サポート。そろそろこれが切実に欲しくなってきました。DL1の時も未サポートだったけど、DL2になって大部分がrubyで書かれるようになったのでそろそろ手を入れてみようか。。。
  • a=struct(["int m[10]"]).mallocの時、a.m[2]=1は意味を成さない。a.mの時点でArrayに代入されたコピーになるため。tmp=a.m;tmp[2]=1;a.m=tmpと書く必要がある。ここはなんとかならないかな?CArrayとかでっち上げてあげてみるとか。
  • a=struct(["char buff[3]"]).mallocの時、a.buff="ab"の意味がかわってる。DL1の時は確か[?a,?b,0]の意味だったがDL2は配列の数が合わずにエラーになる。a.buff="ab\0"のように明示的にNULL文字を入れる。

他 Web上の参考になる情報

間違ってたら誰か突っ込みお願いします。。。
後、こんなのもよくひっかかるとか。