2003-11-11 (Tue) [長年日記]
_ monitor.rb
Gennady Bystritskyさんという人から変更の提案をもらったのでコードの見直し。
あまりにもひどいので、テストを書いてリファクタリング。 rubyのtest/以下にテストがいろいろあるようだけど、lib直下のライブラリの テストはどこに置くべきなんだろう。
まあ、とりあえずコードだけcommitしとくか。
_ attribute parameter中のtypeof(void)
mcs(monoのC#コンパイラ)で、
[SatherNameAttribute("times!")] [IterReturnTypeAttribute(typeof(void))] public static __itertype_times __iter_times(int self) { return new __itertype_times(self); }
のようなコードをコンパイルしようとすると、
int.cs(301) error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression
のようなエラーになるようだ。
mcsのソースの該当部(attribute.cs:137)を見ると、
if (e is Constant) { result = ((Constant) e).GetValue (); return true; } else if (e is TypeOf) { result = ((TypeOf) e).TypeArg; return true; } else if (e is ArrayCreation){ result = ((ArrayCreation) e).EncodeAsAttribute (); if (result != null) return true; } result = null; Error_AttributeArgumentNotValid (loc); return false;
となっている。
TypeOfはtypeof演算子に対応する抽象構文木のノードを表現するクラスなのでtypeof(void) も許されそうなものだが、実はtypeof(void)はTypeOfVoidという別のクラスで表現されていて、 しかもTypeOfとTypeOfVoidには継承関係がないらしい。
ECMAの"C# Language Specification"を見てもとくにtypeof(void)だけ除外するような 記述はなさそうだし(いつものように斜め読みだけど)、Visual C#では上記のようなコードは 通るようだ。 ってことはmcsのバグかな。 (cvs updateしたら直ってたりして…最近そういうことがよくあるのだ。)
2003-11-12 (Wed) [長年日記]
_ attribute parameter中のtypeof(void)
会社でcvs updateしても直ってなかったので、パッチを Bugzillaに登録。 実はBugzilla使うのははじめてだったけど、思ったよりスムーズに登録できた。
_ ユニットテスト
lib直下のライブラリのユニットテストはtestの下にそれぞれディレクトリを作るらしい。 というわけで、test/monitor/test_monitor.rbをcommit。
わたなべさんのチェックによって、タイミングによってテストが通らないケースが あることが判明したので、テストケースを修正。わたなべさんに感謝。
ちなみに自分のマシンでは再現しなかったのだが、 マシンが速い(Pentium M 1.5GHz)せいだろうか。
2003-11-17 (Mon) [長年日記]
_ zsh
今更ながらbashからzshに転向した。
サンプルの.zshrcのcsh風なプロンプト(何でこういうとこだけcsh風なんだろ)が 気に入らなかったので変更。
PS1='%m%(!.#.$) '
やっぱりzshは便利だ。 便利だなーと思っていろいろいじっていたら、今日やろうと思っていた他の作業が ぜんぜんできなかった。
2003-11-18 (Tue) [長年日記]
_ Centrino under Linux
CentrinoのLinuxサポートをIntelに求める署名をした。
_ インデント幅
昔rubyでコードを書く時のインデント幅を3にしたいた理由が思い出せなかったのだが、 Satherの影響のような気がしてきた。
_ イテレータの動的分配
Satherコンパイラで イテレータの動的分配ができるようになった。
abstract class $TIMES is times!(once n: INT): INT; end; class TIMES < $TIMES is create: SAME is return new; end; times!(once n: INT): INT is i ::= 0; loop while!(i < n); yield(i); i := i + 1; end; end; end; class MAIN is main is t: $TIMES := #TIMES; loop i ::= t.times!(3); #OUT + "i=" + i + "\n"; end; end; end;
_ parameterrized type
どういう実装にするのかが悩ましい。
内部的には全部System.Objectにして、INTとかはboxingすればいいかなとも思ったけど boxingのオーバーへッドが気になるところ。 あと、.NETの配列をどういう扱いにするかって問題もあるし。
といって、パラメータとして与えられた型毎にクラスを作るのも、生成したクラスをどの アセンブリに含めるかが悩ましい。
C#で実装されるのを待つか…。
2003-11-19 (Wed) [長年日記]
_ self.foo = x
Rubyでprivateなsetterを
self.foo = x
のように、selfを指定して呼び出せるようにしたらどうか、と提案しようと思って、 念のため確認してみたらRuby 1.8ではできるようになっていた。
Thu Feb 20 04:07:06 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net> * parse.y (attrset): "self.foo=x" can be legal even when "foo=" is private.
負けた…。
その後、IRCでsetter以外のprivateメソッドでもself.fooという書き方を許した方が よいのでは、という話題に。
個人的には、Rubyを覚えたころに、
- privateメソッドはレシーバを指定して呼び出せない。
- 関数風のメソッドはprivateメソッドで提供する。
という仕様に非常に感銘を受けたので何となく抵抗があるけど、上記のような仕様の方が 驚きは少ないかもしれない。
_ homogeneous/heterogeneous
GJのようにtype parameterをSystem.Objectに変換するものをhomogeneous、 C++みたいにtype parameterごとに別々の型をインスタンス化するものをheterogeneousと 呼ぶらしい。
もともとparameterrized typeがなかった言語に追加する場合には、homogeneousの方が ライブラリの互換性の面から好ましいようだ。 とすると、C#にはhomogeneousなparameterrized typeが導入されるのかなあ。 (ん…、Visual C++はどうしてるんだろう。)
_ signatureとsupertyping
GNU C++の拡張にsignatureという機能がある。
<URL:http://www.sra.co.jp/wingnut/gcc/gcc-j.html#C++%20Signatures>
signatureの利点を上記URLから抜粋:
2. シグネチャを使うと、既存のクラス階層をシグネチャ型の実装と して使うことができる。もしこのクラス階層がコンパイルされた 形でしか利用できないとすると、抽象仮想クラスを使うときに困 ることになる。抽象仮想クラスは既存のクラス階層の一番上に後 から取り付けることはできないからである。このため、インター フェースクラスをその抽象仮想クラスの下位型として書く必要が ある。
Satherの場合は、「抽象仮想クラスは既存のクラス階層の一番上に後から取り付けること」 ができるようになっている。それがsupertypingだ。
abstract class $FLT > FLT, FLTD is flt: FLT; end;
のように定義することで、新しく作成した$FLTを既存のクラスFLT・FLTDのsupertype にすることができる。
babel(いーかげんちゃんと名前を考えなきゃ)ではどうやって実装しよう…。 既存のクラスをsupertype化する時は、アダプタになるクラスを自動生成するようにして、 必要になった時にアダプタを生成すればすればいいかな(boxingみたいに)。
_ parameterrized
parameterrizedじゃなくてparameterizedだった。 馬鹿丸出し。
2003-11-20 (Thu) [長年日記]
_ new
newに型名を与えられるようにした。 これで、他の言語で定義されたクラス(createメソッドを持たない)もインスタンス化 できるようになった。
class MAIN is main is Gtk::Application::Init; win ::= new Gtk::Window("Gtk# Hello World"); win.ShowAll; Gtk::Application::Run; end; end;
こんな感じで、Gtk#でウィンドウが表示できたのでちょっとうれしい。
new GTK::Window("Gtk# Hello World")
は
#GTK::Window("Gtk# Hello World")
みたいに書ける方がいいのかなあ。
2003-11-21 (Fri) [長年日記]
_ コマンドラインオプション
いくつかのコマンドラインオプションを追加。
$ ./bsc.exe -help usage: bsc [options] source-files -lib:PATH1,PATH2 Adds the paths to the assembly link path -out:FNAME Specifies output file -reference:ASS References the specified assembly (-r:ASS) -target:KIND Specifies the target (KIND is one of: exe, winexe, library, module), (short: -t:) -help Print this message
これでライブラリが作れるようになった。
_ using?
そろそろnamespaceの使用を宣言する構文を導入したいけど、予約語の名前が 決らない。
C#だとusingだけど...うーん。Java風にimportとか? というかいっそのことターゲットを Java VMに変えるか。(本末転倒)
2003-11-26 (Wed) [長年日記]
_ supertyping
supertypingを実装。
これで、
abstract class $STR > STR, BOOL, INT is str: STR; end;
のように既存のクラスのスーパータイプを定義することができるようになった。
2003-11-27 (Thu) [長年日記]
_ mcsのbug
前に報告したbugがfixされていた。
<URL:http://bugzilla.ximian.com/show_bug.cgi?id=50839>
気をきかせてinterfaceを使うパッチを送ったけど、素直に継承した方がよかったか。
_ let
何か最近日記の更新が上手く行かないと思ったら、.emacsの
(defun commit-diary () (interactive) (save-buffer) (cd www-directory) (shell-command "make install"))
を
(defun commit-diary () (interactive) (let ((dir (pwd))) (save-buffer) (cd www-directory) (shell-command "make install") (cd dir)))
とした後で、(pwd)が"Directory ~/"みたいな文字列を返すので上手く行かないことに気付いて、 あわてて、
(defun commit-diary () (interactive) (let (save-buffer) (cd www-directory) (shell-command "make install")))
と直したせいだった。 (letを消さずに((dir pwd))だけ消したので(save-buffer)がletの第一引数として 扱われてしまった。)
最近ほとんどLispをいじることはないので、何回見ても誤りを見付けられなかったのだが、 やっぱり私はLispに向いてないのかもしれない。 (けっこう好きなんだけどな。)
_ 原さん
会社に原さんが来た(アウディのTTで!)。数学の会議で松江に来ていたらしい。
Haskellのモナドの話になって、原さんは「私にわからんのは(Haskellが)おかしい」と言っていた。 原さんにわからないなら、私にわかるわけがないな。