2007-05-03
■ [scheme] SICPはじめました
http://sicp.g.hatena.ne.jp/yhara/
なんとなく勢いでSICP(日本語版)を買ってしまったので、淡々と問題を解いていこうかなと思います。 ユニットテストが書けそうなものはgauche.testを使ってテストファーストで。
■ [ruby] Ruby/AnarchyGolf
Hpricotを使って、AnarchyGolfのスクレイパを書いてみました。
使用例。
yhara@meteor:~/HTML/anagol % irb -r lib/anagol.rb >> anagol = AnarchyGolf.new => #<AnarchyGolf:0x2aaaac15e9f0 @html={}> >> langs = anagol.languages => [#<struct AnarchyGolf::Language name="Ruby", short_name="rb">, (中略), #<struct AnarchyGolf::Language name="x86", short_name="out">] >> probs = anagol.problems => [#<AnarchyGolf::Problem:0x2aaaacf21600 @name="hello world">, (中略), #<AnarchyGolf::Problem:0x2aaaacf1dd70 @name="128 bits">] >> hw = probs.first => #<AnarchyGolf::Problem:0x2aaaacf21600 @name="hello world"> >> hw.name => "hello world" >> hw.url => "http://golf.shinh.org/p.rb?hello+world" >> hw.description => "say "Hello, world!"" >> hw.deadline => nil >> hw.revealed? => false >> hw.ranking["Ruby"].first => #<struct AnarchyGolf::Problem::Score rank=1, lang="Ruby", user="eban", size=19, score=nil, time=0.1226, date="07/01/30 16:37:51", stat="?B / ?B / ?B"> >> hw.language_ranking.first => #<struct AnarchyGolf::Problem::Score rank=1, lang="PHP", user="konbu", size=13, score=10000, time=nil, date=nil, stat=nil> >> hw.has_language?("Befunge") => true
problemsを呼んだときに各問題に対応するProblemのインスタンスが生成される……のですが、 problemsを呼ぶだけで全問題のURLにアクセスするとサーバに負荷がかかりすぎるので、 Problem#descriptionやProblem#rankingといったプロパティは「実際にアクセスされたときに初めて値を取りに行く」 ようになっています。
実装はこんな感じ。
module CachedAttribute def cached_attr_reader(*syms) syms.each do |attr| module_eval <<-EOD def #{attr} if defined? @#{attr} @#{attr} else @#{attr} = update_#{attr} end end EOD end end end class AnarchyGolf class Problem extend CachedAttribute cached_attr_reader :description, :deadline, :revealed cached_attr_reader :ranking, :language_ranking ... def update_ranking # 最初にProblem#rankingが呼ばれたときだけ実行される
さて、何がやりたかったかというと、UnlambdaとかErlangとかマイナーな言語の簡単なサンプルコードが欲しかったのでした。 *1 とりあえずanagol tableを作って目的は達成された…のですが、 実際にコードを見たところでgolfされてるから意味不明という罠が。しまった!
*1 最近の問題は一定時間で回答が公開されるようになってたりする