万葉.rbに参加しました

 日付変わって昨日、万葉.rbに参加してきました。途中から「発表すればよかったな……」と思いつつ最後までたのしく聞きました。その時メモしようと思ったことは大体ついったでつぶやいたのでそっちを参考に。(自分用に続きを読むにtwilogのソースを貼りつけた)今いろいろ悩んでいることの参考になることがありました(懇親会を含め)。もっと話しかけようと思いました。あと発表しようと思いました。
 勉強会+お祝いムード満載でとってもいい空間でした。6周年おめでとうございます!
 あとたこ焼きおいしかったです。


 つづきからtwitterのログ。

続きを読む

リーダブルコードを読ませていただいたので

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

といっても、読んだのは随分前です。だけども読ませていただいたからには感想をどこかに載せるべきだと思うので。

本は、実践するのは難しいかもしれないことを、どうすればいいかわかりやすく書かれていて、これやってみようかな、と思う内容でした。名前の付け方とかのコードの「見た目」の話から始まって、ifはこういう時に使う、というようないかにわかりやすい構造にするか、という話で、色んな方面から「リーダブル(=わかりやすさ)」にするにはどうするか、を説明されている印象でした。
1つ1つの問題ごとにこの流れを丁寧に、だけど簡潔に行っていて、すらすら読みやすい。一つ一つの問題も具体的なので、こういうコードあったら確かにこうしたほうがいいな、と理解しやすかったです。原理原則の説明の後に具体例がたくさんあったので、さらに理解しやすかったように思います。
あと個人的には、コードにコメントを残すな、というのを昔誰かに教わって以来あまりコメントをコードに書いてこなかったのですが、本書を読んでからコメントを残すのに抵抗がなくなった気がします。心なしか。こういうことをコメントに書くのか! と手本を見せてもらったような感じです。
とはいえ、実際にコードを書いて読みやすくできるようになるには、本書を読むだけでなくて他の人に見てもらって添削してもらわないと無理な気もします。まあ読みやすいコードというのは自分以外の人にも読みやすいという意味だから、本書を読んで知識を入れたら他人にコードを読んでもらえる場所で実践して身につける、といった流れが一番の近道だと思います。それこそ解説のやり方を実践するとか!
ついさっき自分が書いたコードが読みやすいのは当たり前ですからね*1。そのコードを他人が、もしくは数日後の自分が読みやすいか、を考えてコードを書くことをがんばりたいと思います。


あと、原著を本書を読む前に読んだのですが、原著の英語も難しくないので読みやすいです。英語の勉強とか英語でコード内にコメント書くときの参考になると思います。こちらには日本語訳についている解説はないですが……。


The Art of Readable Code: Simple and Practical Techniques for Writing Better Code

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code

*1:日本語の文章でもそうですね

RubyKaigi2011でLT喋りました

 すっかり遅くなりましたが一応ご報告まで。
先週のRubyKaigi2011にて、2日目のLTでRubyOSの話を喋りました。
やるおーえすとかYet Another Ruby OSとか色々ふざけましたけどw、ものすごく緊張しながら喋ったりデモをしたりの発表でした。
実機を映してる最中、マイクで片手がふさがった状態で片手でコードを打つのが苦しくて、思わず愚痴をこぼしたらスタッフの方が即座にマイクを持ってくれて感激してました。本当ありがとうございました・゚・(ノД`)・゚・
 会議自体も初めての参加でしたが、全体的に楽しかったです。ってすごいざっくりした感想ですが……聞いた講演については自分用にメモを取ったので、それを見て勉強したりたのしくRuby書きたいと思います。講演の動画はニコ動にあがったりするのかな? 過去のはいくつか見たけど。体調が悪くて聞けなかったりもしたので上がるなら見たいなあと思っております。

 で、急募として、というかいろんな人に言われているので、いつかやろうと思っていたソースコードの公開の準備をちゃちゃっとしようかな……まずしかるべきところに連絡を取って、かつソースのイミフなところを直さないと……いや、中学生コミッタの方が自分の昔のソースコードpgrしてたけど、それどころの騒ぎじゃない件はどうすれば。
そういえばLTの資料をSlideshareとかにアップしたほうがいいのかな。ほぼネタしかかいてないけど。うむ。

使いたいコマンドがどのパッケージに入ってるかわからない時はapt-file search

上記エントリで書いた作業をしていてハマった部分。
探したらこういうことだったのでメモ。
参考にしたのはこちらです。ありがとうございます。

まず、apt-fileが入ってなかったのでインストール。

sudo aptitude install apt-file
apt-file update

そのあと、例えばmakeinfoがどのパッケージにあるかを調べようとして、

apt-file search makeinfo

とやると、色々出てくる中でこういうのを見つけた。

texinfo: /usr/bin/makeinfo

今入れたいのは/usr/bin/makeinfo。ということでtexinfoを入れればいいことがわかった。

magitをインストール

Emacsを使っていて、コミットするのにmagitを使おうと思ったらそんなもんねえよと怒られた。まあ入れてないしね……バイト先で普通に使ってるのでそのノリでやってしまった。
ということで色々調べて入れてみた。どこを見たかはうっかり消してしまった(´・ω・`)
なお、すでにemacsにmagitに対応したコマンドは設定されていて、肝心のmagitがない、という状態からのスタートです。環境はUbuntu11.04。ちなみにVirtualBox4.0.6上で動いてます。


まずはリポジトリを落としてくる。magitの公式はこちら

cd /tmp
git clone git://gitorious.org/magit/mainline.git

できたディレクトリに移動して./autogen.hを実行。

cd mainline
./autogen.sh

autoreconfがないと怒られたのでautoconfを入れた。

sudo aptitude install autoconf
./autogen.sh

configureしてmakeするとmakeinfoがないと怒られたのでtexinfoを入れた。

./configure
make
sudo aptitude install texinfo

そのあとmakeすると通ったのでインストール。

make
sudo make install

emacsの設定ファイル(私の場合init.el)のどこかに次のものを書いた。

(require 'magit)

M-x load-fileで設定を読み込み直したら使えるようになった。

なまはーどるびー(略してNHR)でKernel#sleepを使いたいので調べて無理矢理実装してみた

 略に特に意味はない。使うけど。
で本題。NHRでKernel#sleepを使ってデモをつくろうと思い、Kernel#sleepがちゃんと動くようにした。そのためにまずKernel#sleepがどう動いているのかをざっくり調べていた。
 Kernel#sleepの実態関数はprocess.cにあるrb_f_sleep()で、rb_define_global_function()で関数風メソッド(printみたいなの)として定義されている。
そのrb_f_sleep()内を見て、時間関連の関数を探す。と、time()を2回使っている。
これはどうも、返り値として返す「実際に停止していた秒数」を返すためらしい。ので、とりあえず無視。
次に関係するっぽいrb_thread_wait_for(rb_time_interval(argv[0]))を見ていく。あ、rb_thread_sleep_forever()は名前からして永久に寝ているのでとりあえず無視。
で、rb_time_interval()は数値(というかVALUE型)で渡された値を構造体timevalに変換しているっぽい。
実際に寝る処理をしているのはrb_thread_wait_for()の方のようなので、関数を追っていくと、rb_thread_wait_for()→sleep_timeval()と続く。sleep_timeval()見たらなんかわっさーしている……とりあえず、

    getclockofday(&to);
    to.tv_sec += tv.tv_sec;
    if ((to.tv_usec += tv.tv_usec) >= 1000000) {
        to.tv_sec++;
        to.tv_usec -= 1000000;
    }

の部分で、toに現在の時間getclockofday()を入れて、そこに待ちたい時間tvを足しあわせて終わりたい時間とし、桁の調整をしている。
でそのあとdo-whileに入って、

        getclockofday(&tvn);
        if (to.tv_sec < tvn.tv_sec) break;
        if (to.tv_sec == tvn.tv_sec && to.tv_usec <= tvn.tv_usec) break;

ここでまず現在時間tvnを取得した後、

  • 終わりたい時間toよりも現在時間tvnの秒数が多いとき
  • toとtvnの秒数が同じで、かつtvnのマイクロ秒がtoのマイクロ秒以上だったとき

にwhileを抜けて待つのをやめる。
他の処理に関してはthread関連のようなので、ざっと見た後スルー。多分、本来はスレッドのスリープ(native_sleep())で寝るべきなんだろうなあ。でも今のRubyOSはpthread_cond_wait()が即座に成功の値返して終わっちゃうので、実質は上のdo-whileで待っている状況。いいのかなこれで……まあスレッドもなんもないけど……。
ちなみに上で使われているgetclockofday()は、clock_gettime()と、CLOCK_MONOTONICが定義されていれば使って、ない場合はgettimeofday()を使って時間を返す。なんでそういう優先順位かというと、性能とか精度の問題でだそうで。

 ということで、上記を踏まえてNHRでsleepできるように実装。
 clock_gettime()はタイマ使って作ったけど、CLOCK_MONOTONICなんて定義してないお……ということでRubyインタプリタMakefileのCFLAGSに -DCLOCK_MONOTONICを追加して定義してみた。
コンパイルしてQEMUにて実行。現在RubyOSには、キーボードから入力された文字をRubyスクリプトとして実行する(もんのすごい一部分の機能しか使えないけど)スクリプトがOSコードとして乗っているので、それを使ってsleepをしてみたらちゃんと待っているので多分OKだろう……。ちなみに、clock_gettime()の中身をコメントアウトしてすぐにreturn 0するようにしたらsleepしても待たなくなった。
ただ、time()は実装していないので、返り値は常に0になる。この辺もちゃんとやるべきだろうか……。というか、タイマが起動してからの刻みなので、具体的な日付とか時刻が出せないのはどうすればいいんだろう。RTCとか?