2010-03-19
■ [prog] GC(ガベージコレクション)に特化した日本語書籍が発売、"早くも出版社在庫は品切れ"
@nari3と@_hikari_によるGC本が発売された。監修は竹内先生。 予想を上回る売れ行きに、既に出版社在庫が品切れらしい。どういうことなの…。
ガベージコレクションのアルゴリズムと実装(中村 成洋/相川 光)
[5F] 『ガベージコレクションのアルゴリズムと実践』中村成洋ほか¥3360(秀和システム)レジ前の新刊コーナーと情報科学のコーナーにて平積みしています。早くも出版社在庫は品切れです。購入を予定されている方はお早めに!!
[Twitter / 書泉グランデ: [5F] 『ガベージコレクションのアルゴリズムと実践 ...より引用]
「GC(ガベージコレクション)」は、プログラムの実行中に不要になったメモリを自動的に解放する機構のこと。 JavaやRubyを始め、現代においてはGCのない言語処理系の方が珍しいくらいだ。
そんな重要なGCであるが、GCを専門に扱った書籍は、いままでに洋書の「Garbage Collection」の一冊しかなかった。 世界で二冊目のGC本が、日本から出たというのは、なかなか凄いことじゃなかろうか。*1
さて一口にGCと言っても、メモリ効率を重視したもの、トータルの実行時間を重視したもの、一回の停止時間を重視したものなど、 さまざまなアルゴリズムと実装が存在する。本書では、代表的な8つのアルゴリズムと、実際の4つの言語処理系のGCの実装について解説されている。
●序章 GCとは / GCの恩恵 / GCの歴史 / なぜ今GCなのか / 読者対象 / 本書の表記 ●アルゴリズム編 第1章 GCを学ぶ前に 第2章 マークスイープGC(Mark Sweep GC) 第3章 参照カウント(Reference Counting) 第4章 コピーGC(Copying GC) 第5章 マークコンパクトGC(Mark Compact GC) 第6章 保守的GC(Conservative GC) 第7章 世代別GC(Generational GC) 第8章 インクリメンタルGC(Incremental GC) ●実装編 第9章 PythonのGC 第10章 DalvikVMのGC 第11章 RubiniusのGC 第12章 V8のGC ●補遺 補遺A 簡単言語入門:Python編 補遺B 簡単言語入門:Java編 補遺C 簡単言語入門:Ruby編 補遺D 簡単言語入門:JavaScript編 補遺E 参考文献
Pythonはご存じとして、DalvikVMはAndroid用のJava VM、 Rubiniusは「できるだけRubyで書く」Ruby処理系、V8はGoogle Chromeに搭載されているJavaScript処理系だ。
人生で3回GCを実装しているというまつもとゆきひろ氏*2による帯の文章も格好いいので、書店で注目してみてほしい。
2010-03-18
■ [ruby] Hashのデフォルト値にHashを設定しようとしてはまった話
h = {}
ary.each do |x, y, z|
h[x] ||= {}
h[x][y] = z
end
をもっと短くしようとして、
h = Hash.new{ {} }
ary.each do |x, y, z|
h[x][y] = z
end
としたら上手く動かない。あれっ?
デフォルト値が{}じゃなくて数値の場合、例えば
h = Hash.new{ 0 }
ary.each do |x|
h[x] += 1
end
みたいのはちゃんと動くわけです。上のとどう違う?
h[x][y] = z
はどういう動作になるか考えてみよう。
- hにxというキーがある場合: h[x]というハッシュに、(y, z)のペアを保存。
- hにxというキーがない場合: ブロックが呼ばれて、その値が返る。返り値であるハッシュに、(y, z)のペアを保存。
というところで気づきましたが、後者が原因ですね。毎回新しいハッシュが作られて捨てられてしまう!
というわけで
h = Hash.new{|h, k| h[k] = {} }
ary.each do |x, y, z|
h[x][y] = z
end
が正しいコードでした。
まあ素直に冒頭のように書けばいい気もしますが。
■ [ruby] メソッドが最初に呼ばれたときだけ処理を実行する
例えば、重い計算をキャッシュしたい時とか。
begin-endを使うとこう書ける。
def start_server
@started ||= begin
# 重い計算
true
end
end
(以下、余談)
ただなー、偶然@startedという名前が被ってしまう可能性が残ってしまうのが気になる。
こういう場合、Schemeとかだと以下のようにして関数ローカルな状態変数を作れる。
(let ((started #f))
(define (start_server)
(unless started
; ...
(set! started #t))))
Rubyで同じことができないかと思ったが駄目だった。
proc{
started = nil
def start_server
started ||= begin #=> このstartedはfooのローカル変数になってしまう
# ...
true
end
end
}.call
■ [ruby] Ruby 1.9.2のリリースプランが発表 (7月末リリース予定)
- 3月末日 : 仕様の凍結 (この日までに合意が得られなかった仕様・修正は1.9.2に入らない)
- 4月末日 : コードの凍結 (この日までに実装できなかった仕様・修正は1.9.2に入らない)
- 5月末日 : 1.9.2-preview2
- 6月末日 : 1.9.2-rc
- 7月末日 : 1.9.2-p0 (正式リリース)
ということで、8月末のRubyKaigi2010に合わせた感じになったようです。
Ruby 1.9.2の新機能
Ruby 1.9.2は、既に公開されている1.9.1に対し、完成度を高めたバージョンです。特にTimeクラスの2038年問題が解決されたのが嬉しいですね(最近はまったので)。
この他大きめの新機能の一覧が、先日公開されたRubyist Magazine(るびま)で列挙されています。
Ruby 1.9.2の非互換
重要な非互換としては、$LOAD_PATHに"."が入らなくなったことが挙げられます。
例えば main.rb と util.rb が同じディレクトリにあった場合、従来は main.rbから以下のように直接util.rbを読み込むことができました。
require 'util.rb' ...
ですが、1.9.2ではセキュリティ上の理由から、これができなくなりました (Unix で、PATHに"."が含まれないのと同じでしょうか)。
対応としては、とりあえず「./」を明示的に付ければOKです。
require './util.rb'
が、(元のスクリプトもそうですが) これだと別のディレクトリからmain.rbを起動した際にうまく読み込めません。 Ruby 1.9.2では、現在のファイルからの相対パスでrequireするファイルを指定するメソッド、require_relativeが追加されました。
require_relative 'util.rb'
このようにすると、main.rbと同じディレクトリにあるutil.rbを必ず読み込むことができます。
従来は同じことをするのに
require File.expand_path(File.join(File.dirname(__FILE__), "util.rb"))
と書く必要があったので、特にユニットテスト内からtest_helper.rbを読み込んだりする際にはとても便利になりました。
2010-03-16
■ [ruby] Ruby meets Manpage
manは、Unix系OSで一般的に使われているドキュメントシステムだ。 これを、Rubyのgemに対しても応用できないかという試みが現れた。 その名もgem-man。
gem install gem-man
とすると、
gem man <gem名>
でそのgemの説明が見られるようになる。例えば
gem man gem-man
とか。
ライブラリ作者の側では、gemを作る際にman/以下にmanのファイルを置けばいい。
manファイルの作り方はman whatが参考になりそう (ronnを使う例が載っている)。
おまけ
http://man.cx/ruby : ネットでmanを引けるサイト。
■ [prog][memo] Test Doubleいろいろ
- Ruby Freaks Lounge:第35回 実用的なダミーサーバ ww(double-web)(1)|gihyo.jp … 技術評論社
- Martin Fowler's Bliki in Japanese - テストダブル
| 名前 | インターフェイスの実装 | 用途・備考 |
|---|---|---|
| dummy | 実装しない | 引数として渡すが、使われない |
| fake | 実装する | ただし本物よりは性能などが劣る、仮実装 |
| stub | 実装する | あらかじめ決められたものを返す |
| mock | 実装する | 期待した呼ばれ方かどうかをテストする |
| spy | 実装する | 呼ばれ方を記録して、あとで確認する |
■ [ruby] Rubyスクリプトをcronで回したいときはどうすれば良い?
ありがちな罠:
- PATHがいつもと違うせいので、portsで入れたやつじゃなくてMac標準のRubyが実行される
- GEM_HOMEがいつもと違うせいで、ライブラリが読み込めない
- RUBYOPT=rubygemsがないせいで、ライブラリが読み込めない
というのを避けるためには、どうするのが正しいんでしょう。
とりあえずcrontabの冒頭でこれらを設定することでなんとかなったが。
PATH=/Users/yhara/bin:/opt/local/bin:/opt/local/sbin/:/usr/local/bin:/usr/bin GEM_HOME=/some/where RUBYOPT=rubygems 0 * * * * /Users/yhara/proj/etc/cron_hatenagraph/hatena_graph.sh
2010-03-15
■ [gadget][prog] iPadは「プログラミング黄金時代」の終焉の始まりか?
来月に発売が予定されているiPadを以て、アップルは「パソコン」を置き換えようとしているように見える。 インターネット、メール、ゲーム、ワープロ、表計算。普通の人がパソコンに求める大半の機能が用意されている。
だけど、プログラミングはできない。
iPadには「ターミナル」も「コマンドプロンプト」もないし、実用的なプログラミングを学べるようなアプリも作ることができない (irbのような、実行時に動作が大きく変わり得るものは申請してもアップルの検閲を通らない)。
そのうち、物心ついて最初に触ったマシンがiPad、という世代が出てくるだろう。 さて、彼らはどうやってプログラミングの楽しさに出会うのか?
iPadと同カテゴリになりそうなChrome OSも、ネイティブアプリは一切動かせないので同様の問題を抱えている。 「次世代のパソコン」として覇権を握るのがiPadなのか、Chrome OSなのか、Androidなのか、あるいはこのままWindowsがシェア一位を保つのか分からないが、 どんな言語の処理系も、ネットからダウンロードするだけですぐにプログラミングが始められる現代を「あの頃はプログラミング黄金時代だったよなぁ…」と振り返る未来は避けたいところだ。
■ [prog] iPadでなんとかしてプログラミングを体験する方法を考える
補足しとくと上の「プログラミング黄金時代」は http://www.nicovideo.jp/watch/sm8249954 からです。
JavaScriptで頑張る
ブラウザ内でFlashプログラミングができるwonderflというのがあるが、 あれのJS版 (wonderjs?) を作れば、iPadのSafariでもJavaScriptでプログラミングが楽しめる。(wonderfl自体は、FlashなのでiPadでは使えない)
言語がJavaScriptに限られるけど、これは「JavaScriptで別の言語の処理系を作る」という奇手である程度対応できる。BiwaSchemeのようにね。
コードは別のマシンで動くことにする
Ruby用レンタルサーバのHerokuが昔やっていたように、クラウドで動くアプリをブラウザ上で書けるような何か。
うーん
どっちにしろVimで書けないので僕は使いたくないですね :-(
2010-03-11
■ [ruby] RubiniusのJITコンパイル
開発者Evan Phoenixの記事。
http://www.engineyard.com/blog/2010/making-ruby-fast-the-rubinius-jit/
■ [ruby] 世界のRUG (Ruby User Group)
http://www.rubyusergroups.org/
宝石がグループ、人型がユーザ。南米が熱いな。

via RubyInside

□ rui [letの中に書いてもtop-level define扱いなんでしたっけ? こういうふうに書いたほうがよさそう。 ..]
□ yhara [どうなんでしたっけ?(おい) その方が良さそうですね。ありがとうございます。 (もとのstart_serverは..]