丁稚な日々

Rubyで遊んだ日々の記録。あくまで著者視点の私的な記録なので、正確さを求めないように。
Rubyと関係ない話題にはその旨注記しているはず。なので、一見関係無いように見える話題もどこかで関係あるのかもしれません。または、注記の書き忘れかもしれません...

[直前] [最新] [直後] [Top]

Feb.13,2007 (Tue)

Revision: 1.5 (Feb.15,2007 22:26)

[あなごる] delete last line

_ すっかりawkスキー。

_ 19Bを作ったところで、御大に16Bというのをやられる。
悔しかったのでズルして6B。ズルした後で16Bをどうやるか気付く。
ああ、ズルはもうしないと誓ったはずなのに...

[あなごる] sort characters

_ やっぱりawk。
ソートのアルゴリズムを変更して、コードを最適化して93B。

[あなごる] Square root

_ 当然awk。
諦めてmawkをインストールしたのでいろいろ試す。
ってなんじゃこりゃー。25B。
awk最強かよ!

[あなごる] swap lines

_ しつこくawk。
なんか書いててだんだんわからなくなってくるが、とにかく20B。

Feb.14,2007 (Wed)

Revision: 1.2 (Feb.15,2007 22:21)

[あなごる] awkスキー

_ awkは楽しい。やればやるほど楽しい。ヤバイ。

_ invert caseは御大がズルの方が圧倒的に短いことを発見して短くなった。
さ、先にズルしたのはあたしじゃないんだからねっ!

_ これまでに得た知見を元にtennisを淡々と進める。

_ 途中でふとsort charactersを短くできる可能性に気付く。
最初はバブルソート、その後バケツソートに移行していたのだが、再びバブルソートに戻してみる。ふむ、10B近く短くなった。
そこからさらにコードを最適化して65B。

_ tennisに戻って128B。
とりあえずこんなもんか?

_ あ、Rubyでtennisでしょぼいの登録してますが、tennis.awkをupするつもりで間違えたのでした。しょぼん。

_ 1:38現在のLanguage RankingではRubyが総合・平均(1問しか解かれてないx86はスルー)とも1位。すばらしいね。
現在一押しのawkは総合3位。Pythonよりは常に上にありたい。
御大やshinhさんが頑張ってるsedもジリジリ来てる。

Feb.15,2007 (Thu)

Revision: 1.2 (Feb.15,2007 22:36)

[mswin32] __pioinfo[]

_ [ruby-core:10259]で発覚した問題の話。
簡単に言うと、SP1を適用したVC++8(Visual C++ 2005)でminiruby.exeまでは作れるけど正常に動作しない、というもの。

_ 前にVC++8対応した時もioinfo構造体の中身が変更されていたのだが、どうやらSP1でまたなんか変わったらしい。
Cランタイムのソースが今回は出てきていない(たぶん)ので詳細はよくわからないが、おそらく後ろに新しいメンバ変数が追加されたのだろうという仮定の下に試行錯誤してみたところ、ioinfo構造体のサイズが16バイト大きくなっていたということがわかった。
それを除けば、rubyが使っているメンバ変数に関しては意味もオフセットも変更されていないようではある。

_ 問題はこれをどう判定するか、なのだが、msvcr80.dllのバージョン番号を取ってきて判定することにした。泥臭い。
configure時にチェックすればいいか、と一瞬思ったが、古いmsvcr80.dllを対象にコンパイルされたバイナリもアセンブリバージョンのリダイレクト(%WINDIR%\WinSxS\Policiesを利用する奴)を使って華麗に新バージョンのmsvcr80.dllを利用するようになっているので、実行時にチェックするしかないらしい。くすん。

_ そもそも、__pioinfo[]なんていう内部データを利用しようというのが根本的な間違いだと言ってしまえばそれまでなのだが、じゃあこれを捨ててfile系とsocket系を統合したIO機構を全部自前で実装しろと言われると...

_ こういう時は先達をチェックするに限る。
perlさんはPerlIOという素敵な仕組みを持ってるはずだが、前に見ようとしてそのコードの複雑さに断念した記憶があるのでとりあえずパス。
というわけで、pythonさんをチェックすることにする。2.5。

_ まず、file系は言うまでもなくfileオブジェクト。
中身はstdioベースで実装されている。ふむ。
続いてsocketはというと、socketモジュールのsocketオブジェクト。
ここまではruby 1.8と同じだが、socketオブジェクトはfileオブジェクトとは直接の関係はなくて、Cのsocketの薄いラッパになっている。ふむ。
socketオブジェクトからfileオブジェクトへの変換はsocketmakefileメソッドで行えるが、Windowsだとmakefileメソッドはない(ので変換できない)らしい。
なるほど、割り切ってるなー。というか、rubyのWindows実装の諦めが悪いだけなのか。

_ と、いうわけで、rubyでもSocketIOのサブクラスじゃなくして実装分離するのはどうですか?
... そうですねダメですね orz

[mswin32] Dir.glob on 1.8

_ 木村さんのパッチがruby_1_8に入った。すばらしい。
木村さん、knuさん、ありがとうございます。
口を出すだけで手を動かさない俺はちょっと吊ってきた方がいいな。つーかgolfしてないでやれよ>俺

Feb.16,2007 (Fri)

Revision: 1.9 (Feb.16,2007 19:15)

[Web] 3000年問題?

_ アプリが不正終了の可能性 / 今度は「3000年問題」、Visual C++に」という話があることをさかきさんに教えてもらった。

_ 感想としては、「お前ら気付くの遅すぎ」と、「問題が出るのは3000年12月31日以降だっつってるだろ」といったところか。
あ、「32bit版でも起きるっつーに」というのもあるな。
なおリファレンスの_mktime64()のところなんかにはちゃんとその制限時刻は書いてあるのだが、_mkgmtime64()のところに書いてないのはいまいちではあるな。

_ おまけ。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

main()
{
    struct tm tm;
    time_t time;

    memset(&tm, 0, sizeof(tm));
    tm.tm_year = 3001 - 1900;
    tm.tm_mon = 1 - 1;
    tm.tm_mday = 1;
    time = _mkgmtime(&tm);
    printf("0x%llx : %d-%02d-%02d %02d:%02d:%02d\n",
           time,
           tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
           tm.tm_hour, tm.tm_min, tm.tm_sec);
    time += 8 * 60 * 60;        /* 8 hours later... */
    tm = *gmtime(&time);        /* good bye */
    /* never reach here */
    printf("0x%llx : %d-%02d-%02d %02d:%02d:%02d\n",
           time,
           tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
           tm.tm_hour, tm.tm_min, tm.tm_sec);
}

というわけで、3001-01-01 08:00:00 UTCに死ぬ気がする。
この8時間はどっから出てきたんだろう? 米西海岸標準時か?

[mswin32] __pioinfo[]

_ 昨日の続き。

_ 結局、Perlも見てみた。

_ PerlIOの仕組みを自分なりにざっくりと今回の話に関係のある部分で捉えると、各IOごとに、規定されているプリミティブな関数群を用意し、処理系は実行時にIOごとのこの関数群を組み合わせて呼び出して高レベルの処理を行う、ということになるのだろうと思う。
つまり、各IO間では実装は可能であれば共有する(同じプリミティブ関数を使う)が、可能でなければそれぞれ個別の実装を用意する。
そういうフレームワークを作っておいて、処理系本体内での処理は各IOで共通化しているということになる。

_ で、WindowsにおけるIO処理はどうなってるかというと、えーと、rubyと同じだな。
__pioinfo[]触ってるのも同じ。というか、rubyの実装がperlを参考にしてるんだろうと思うが。
うーん、ここでPerlIO_win32PerlIO_win32socketとかいう感じで分離してたりしないかと思ったんだけど、そういうわけじゃないのかあ。
select()に関してはsocketにしか効かなさげ。

_ ところで、win32/win32.hのioinfo構造体の定義を見る限り、VC++8 SP1はおろかVC++8にも対応してないように見えるんだけど、ええんじゃろか?
これはstableじゃなくてdevelを見るべきか。
というわけで見たら、2006-11-06にVC++8には対応した模様... と思ったら2日後にその部分は巻き戻されてるな。
部外者だから事情はぜんぜんわからんけど、これは誤解で巻き戻されたんじゃないだろうか?
MSVCR80.dllで__pioinfo[]いじるならこれは必須のはずなんだがなあ。
PerlCRTがあってそっちを使うからどうでもいいってこと?

Feb.17,2007 (Sat)

Revision: 1.4 (Feb.17,2007 04:08)

The Ruby VM Serial Interview

_ James Edward Gray IIさんによる、まつもとさんとささださんのインタビュー。
現時点(03:20)でEPISODE Iのみなんだけど、ということはおそらく続くのだろう。

3000年問題

_ そうそう、昨日の件、忘れる前に書いておこう。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static void invalid_parameter(const wchar_t *expr, const wchar_t *func, const wchar_t *file, unsigned int line, uintptr_t dummy)
{
    printf("somthing wrong!\n");
}

main()
{
    struct tm tm, *ptm;
    time_t time;

    _set_invalid_parameter_handler(invalid_parameter);
    memset(&tm, 0, sizeof(tm));
    tm.tm_year = 3001 - 1900;
    tm.tm_mon = 1 - 1;
    tm.tm_mday = 1;
    time = _mkgmtime(&tm);
    printf("0x%llx : %d-%02d-%02d %02d:%02d:%02d\n",
           time,
           tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
           tm.tm_hour, tm.tm_min, tm.tm_sec);
    time += 8 * 60 * 60;        /* 8 hours later... */
    ptm = gmtime(&time);        /* good bye */
    if (ptm)
        printf("0x%llx : %d-%02d-%02d %02d:%02d:%02d\n",
               time,
               ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday,
               ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
}

というわけで、普通(あくまでVC++8的に「普通」ってことだけど)にエラーをハンドリングすりゃいいんです。
かく言う私も1年ちょい前はこのこと知らなかったんだけどね。artonさんありがとうございます。

_ そもそもVC++7.1まではtime_tの2038年問題(2036年問題だったかも)があったわけで、それが3001年まで延びてるんだからいいじゃん、という気がする。
範囲外の値の処理に関してはEINVALを扱えばよかったのがエラーハンドラの導入が必要になってるという面はあるが、ふつーにVC++8でコード書いたらどうせこのハンドラの導入は必要だし。
そもそも、無限の未来をtime_tで扱おうなんて考えてるまともなプログラマはこの世におらんでしょ。

_ 個人的には、こんなどうでもいいことより、負のtime_t値を受け付けてくれないことの方をどないかしてほしい。

Feb.19,2007 (Mon)

Revision: 1.4 (Feb.20,2007 18:19)

[Web] 去年の話

_ なんだっけ」というのは、このときの話です。
これ読むまでハンドル設定しないといけないこと知らなかったのでした。てへ。

[Web] つくし

_ 頭が開ききる前に採らないと食えなくなるよ! とか思ってしまう。
でも、世間では食べる時に頭を取っちゃう人もいるみたいだな。

[mswin32] VC++8 SP1対応

_ trunkには放り込んであるわけだが、1.8はどうしよう?
入れないでコンパイルできないのもまずいが、adhoc過ぎてなんとなく入れたくないという思いもある。
誰かなんか改善案ないですか。

[あなごる] awk

_ 寂しいので、みんなもっとawkやろうよ〜。
awk歴実質2週間程度という人が頑張ってる現状はよくない。

Feb.20,2007 (Tue)

Revision: 1.2 (Feb.20,2007 23:54)

被捕捉アンテナ類
[Ant] [Antenna-Julia] [Rabbit's Antenna] [Ruby hotlinks]