30th Wed

障害報告

先ほど数分間のあいだ、ブログシステムでエラーが発生しておりました。
現在は復旧しておりますが、ご迷惑をおかけしたことをお詫びいたします。

原因は、deployの高速化のために行った
vendor/railsの削除が正しく適用されなかった事です。

git-svnを利用している場合、rm -rf
などで直接ファイルを削除した後にcommitを行っても、
SVN上のディレクトリが消えない事があるようです。
今回は、直接svnコマンドを利用してremoteのディレクトリを削除することで修復いたしました。

今後ともよろしくお願いします。

posted by genki genki on Wed 30 Jul 2008 at 09:28 with 2 comments

続いては、作表の仕方を紹介します。
このブログシステムは、BlueStoleを参考にして作った作表機能があります。

BlueStole - BlueCloth Wrapper

Ruby の Markdown ライブラリ、 BlueCloth に幾つかの機能を付け足した私家拡張版です。

こんな感じに
RTtool
を使った作表を行うことが出来ます。

|caption=Rendering Algorithm
|
|What , Who , When
|
|Ray Tracing , Whitted, 1980
|Path Tracing , Kajiya , 1986
|Photon Mapping , Jensen , 1995
|Metropolis Light Transport, Veach , 1997

ソースはこんな感じです。

pre>>
|caption=Rendering Algorithm
|
|What , Who , When
|
|Ray Tracing , Whitted, 1980
|Path Tracing , Kajiya , 1986
|Photon Mapping , Jensen , 1995
|Metropolis Light Transport, Veach , 1997
<<--

Rttoolを使っているので、以下のようにちょっと複雑な表も作成可能です。

|Alpha,==,Bravo
|Charlie,Echo,||
|||,Delta,==

ソースはこんな感じです。

pre>>
|Alpha,==,Bravo
|Charlie,Echo,||
|||,Delta,==
<<--

また、このようにCaptionとHeader部分は省略可能です。

posted by genki genki on Tue 29 Jul 2008 at 08:40 with 0 comments

このブログシステムには、いままで外向けのドキュメントが無かったのですが、(潜在)アカウント数が徐々に増えてきた事もあり、利用法を書いておこうと思います。

とりあえずわかりにくい所から。
Syntax Highlightつきでソースコードを書くときは、

ruby>>
class Foo
  def foo; puts "bar" end
end
<<ruby

のように、lang>> <<langで囲んで行頭から書きます。
結果はこの通り。

ruby>>
class Foo
def foo; puts "bar" end
end
<<ruby

langに使えるのは、UltraVioleteで利用可能なもの全てです。
よく使いそうな rails、js、shell もショートカットを用意しています。

あとは、以下のように数式もかけます。

\[math\]
f(x)=\frac{1}{x}
\[/math\]

結果は以下の通り。

[math]
f(x)=\frac{1}{x}
[/math]

この2つはコメントを書くときにも有効です。

posted by genki genki on Sun 27 Jul 2008 at 23:50 with 0 comments

Controllerのアクションのテストを書くときに、
通常は以下のようにgetメソッドなどを使い、
アクションのメソッドを指定します。

rails>>
get :index
<<--

しかし、config/routes.rbの中でmap.root :formulae
のようにルートのPathをindexアクションにマッピングしている場合でも、
get :indexを呼び出した結果、Controllerに渡されるrequest.request_uri
の値は正しいルートのPathになっていません。

そのような場合には、以下のようにすると正しい結果が得られます。

rails>>
request.set_REQUEST_URI '/'
get :index
<<--

posted by genki genki on Sat 26 Jul 2008 at 00:35 with 0 comments

数式をブログに貼り付けて共有するサービス、
Formula
を公開いたします。

formula
http://formula.s21g.com/

Formulaをご利用いただくことで、
誰でも簡単に数式をブログに貼り付けることができるようになります。

例)

Formulaのトップページのフォームから、
LaTeX形式で数式データを入力いただくことで、
Previewを確認しながら好みの数式の画像を生成することが出来ます。

生成された画像は、以下のようなHTMLをブログの記事に記述することで、
埋め込むことができます。

html>>



<<--

また、数式画像をクリックすると、
その数式に関してコメントを投稿することが出来るページにジャンプします。思い入れのある数式にコメントを寄せてみてください。

本サービスに関する各種お問い合わせは、
email
までお気軽にお寄せください。

それでは、よろしくお願いいたします。

posted by genki genki on Fri 25 Jul 2008 at 17:01 with 0 comments

近頃は、GitHubやcutagemのお陰で、
Gemを作ったり公開したりするのがどんどん簡単になってきています。

そうなると、今までRailsプラグインとして作っていた機能についても、
バージョン管理機能を持ったGemの形で公開したほうが便利かも知れません。
そんな時は、RailsプラグインをGemとして公開することができます。

方法は非常に単純で、Gemの中にrails/init.rbを含めるだけです。
あとは、Gem pluginを利用するRailsアプリケーションの中から、
config.gemでGemの参照を設定すればすぐに利用できます。

rails/init.rbの中身は、通常のプラグインのinit.rbと同様です。

posted by genki genki on Thu 24 Jul 2008 at 16:30 with 0 comments

Gitでpatchを作成するには、git-format-patchコマンドを使うと便利です。
メール送信用に整形された状態でpatchが作成されます。
こんな感じでリビジョンを指定して実行します。

pre>>
% git-format-patch -r HEAD~
<<--

0001-Changed-capitalization-of-exts-of-header-files-of-FL.patchのようなファイル名でpatchが作成されます。

作成されたpatchはメール送信用のヘッダ情報などを含んでいますが、
メール送信せずにローカルでgit-am
コマンドを使ってpatchを当てることができます。

pre>>
% git-am ../path/to/patch/0001-Changed-capitalization-of-exts-of-header-files-of-FL.patch
<<--

posted by genki genki on Thu 24 Jul 2008 at 00:25 with 4 comments

RailsのXMLのレンダリングが遅い。
これは、String#to_xsが遅いのが原因らしい。

そこで、これを高速化するためのライブラリfast_xsを使うと、
XMLのレンダリングが速くなります
(手元の環境で試したところでは、若干速くなったような気がしました。)

Rails-2.0以降では、fast_xsがインストールされている場合に、
自動的にそれを利用するようになっています。

[Changeset 7774] Reference current fast_xs URL

インストールは、いつものようにsudo gem install fast_xsでOK。

See Also

 

posted by genki genki on Mon 21 Jul 2008 at 08:37 with 0 comments

masuidriveさんとmemcachedを落とすとエラーが出るのが困るね、という話していて、
fiveruns-memcache-client
を使うと解決しそうという結論に至ったので、ためしに使ってみました。

fiveruns-memcache-clientはGitHubで公開されているので、GitHubからGemをインストールします。

pre>>
$ sudo gem install fiveruns-memcache-client
<<--

つづいて、Railsの環境設定をします。

config/environment.rb

rails>>
Rails::Initializer.run do |config|
(..snip..)
config.gem 'fiveruns-memcache-client',
:lib => 'memcache',
:version => '>1.5.0',
:source => 'http://gems.github.com'
gem 'fiveruns-memcache-client'
end
<<--

gemメソッドをもう一回呼ぶ必要があるのが若干冗長ですね。
これを呼んでおかないと、手元の環境ではオリジナルの
memcache-clientがloadされてしまいました。

さて、あとはデプロイするだけなのですが、
残念ながらfiveruns-memcache-clientを利用しただけでは、
memcachedが落ちている場合にエラーを出さずにcacheを無視してレンダリングするというような挙動はしない模様。
複数のMemcachedを立ち上げておいて、どれかが落ちてる場合は別なサーバにつなぎにいくようにはなるみたいですね。

posted by genki genki on Mon 21 Jul 2008 at 02:46 with 0 comments

以前Hash#sliceが欲しいと書いたことがありましたが、
Rails-2.1のActiveSupportがHash#sliceを実装したようです。

しかし、以前紹介した実装ではValueの配列を返すようになっていたのですが、
Rails-2.1のHash#sliceは以下のような挙動をします。

rails>>

{1 => 2, 2 => 3}.slice(1)
=> {1=>2}
<<--

そう、以前紹介した Hash#only と同じですね。

posted by genki genki on Mon 21 Jul 2008 at 02:03 with 0 comments

このブログシステムをRails-2.0.2からRails-2.1に移行する作業をしています。
このエントリはその作業ログです。

  • benchmark_for_rails でエラーが出るようになったので、
    最新版
    をGitHubからもってくる。
    pre>>
    % ./script/plugin install git://github.com/cainlevy/benchmarkforrails.git
    <<--
  • ActiveSupportでエラーが発生。

    wrong number of arguments (0 for 1)
    /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:301:in `desc'

ソースを見てみると、
ruby>>
def will_unload?(const_desc)
autoloaded?(desc) ||
explicitly_unloadable_constants.include?(to_constant_name(const_desc))
end
<<--
これはおかしい。調べてみたらバグっぽい。

benchmark_for_railsプラグインのlib/benchmark_for_rails/rewatching.rbのL39を以下のように修正。
ruby>>
#rescue NameError
rescue Exception
<<--
プラグイン側ですでに対処されていたのだけれど、
発生する例外のタイプが変わった為にうまく動いてなかったようですね。

  • テストの実行中にTypeError: can't convert String into Integerが発生したので調査。
    このへん
    の問題らしい。パッチを発見。
    rails:freeze:gemsしてパッチを当ててみたが、解決せず。
    • その後調べてみると、どうやらacts_as_searchableのDirtyチェック用コードがRailsの仕組みとコンフリクトしてるのが原因のようでした。
      (See Rails2.1でacts_as_searchable)
  • ActionView::TemplateError: undefined method \stringify_keys' for ...`というエラーが出る。
    • これは自作のHash#sliceが干渉していた模様。Railsで採用されたほうのHash#sliceにインターフェイスをあわせる。
      hash.slice.valuesとすればOk.
  • Viewのテストでundefined method \cache_erb_fragment'というエラーが出る。 cacue_fuのなかで@controller.cache_erb_fragment`が呼ばれているところでエラーが発生しているようだ。
    • Cache関係の自前拡張の影響していたようなので除去。

ここまでで全テストがGreenに。
一通り動作検証をしたのち、Deploy完了。とりあえず問題なく動いているように見えます。

posted by genki genki on Sun 20 Jul 2008 at 20:56 with 0 comments

texvcコマンドを使ってLaTeXで記述した数式の画像を取得するためのラッパーユーティリティとして
Texvc
を作りました。GitHubで公開しています。

インストール方法

まず、texvcを使えるようにする必要があります。texvc
mediawiki-mathパッケージに付属しているので、
適宜パッケージマネージャなどを利用してインストールしてください。
あとは、GitHubからsudo gem install genki-texvcでOKです。

使い方はこんな感じです。

ruby>>
require 'rubygems'
require 'texvc'
Texvc.parse('f(x)=\int_0^x \sin(t),dt') #=> Magick::Image
<<--

結果は以下のようなRMagickのImageになります。

[math]
f(x)=\int_0^x \sin(t),dt
[/math]

posted by genki genki on Sun 20 Jul 2008 at 08:43 with 0 comments

Rubyで一時ファイルを作成する場合は、
Tempfileを使うのが一般的だと思いますが、
今回は一時ディレクトリを作成する方法を紹介します。

TempDir

Jim Freezeさん作のTempDirです。
sudo gem install tempdirでインストールできて、
以下のようにして使います。

ruby>>
require 'rubygems'
require 'temp_dir'
TempDir.create do |dir|
puts dir # => "/tmp/temp_dir_24463_24509_oxvgf"
end
<<--

dirは生成された一時ディレクトリのpathを示す文字列です。
createブロックを抜けると一時ディレクトリは削除されます。

posted by genki genki on Sun 20 Jul 2008 at 07:58 with 4 comments

最近のレンダリングアルゴリズム研究をフォローしていて、
面白そうなものを見つけたのでメモ。

動的モンテカルロ法を用いたフォトリアリスティックレンダリングに関する研究(pdf)

relt.jpg

一瞬LS+DS+E経路問題が解けたのかと思ったのですが、
面光源なので、実際のところLDS+DS+E経路のようですね。ふむふむ。

しかし、MLTと比べて非常に効率よくレンダリングが行われているようです。MCMCのレンダリングアルゴリズムへの応用はなかなか面白そうですね。

レプリカ交換法は抽象的な乱数空間で変
異を定義しており,乱数空間での小さな変異が経路空間上で
は大きな変異になってしまうという問題がある

ふむ。これはMutationをちゃんとやってないって事かな。

posted by genki genki on Sat 19 Jul 2008 at 06:45 with 0 comments

Control Variate
モンテカルロ求積法などでVariance reduction
の為に利用されるテクニックです。

統計量[math]m[/math]が与えられた時、期待値は以下のように表します。

[math]
\mu=E[m]
[/math]

この時、期待値が[math]E[t]=\tau[/math]であり、
相関係数(correlation coefficient)が
[math]\rho_{mt}=Corr[m,t][/math]であるような統計量
[math]t[/math]があるとすると、以下の式で表される

[math]
m^\star=m-C(t-\tau)
[/math]

は、[math]\mu[/math]に対して不偏(unbiased)です。Cは任意の定数です。

ここで、
[math]\sigma_m[/math], [math]\sigma_t[/math]をそれぞれ、
[math]m[/math], [math]t[/math]の標準偏差(standard deviation)
とした時、定数Cを以下

[math]
C = \frac{\sigma_m}{\sigma_t}\rho_{mt}
[/math]

のように選ぶと、
[math]m^\star[/math]の分散は最小化され、以下のようになります。

[math]
V[m^\star]=(1-\rho_{mt}^2)V[m]
[/math]

元の統計量[math]m[/math]の分散に対して、
[math]\rho_{mt}^2[/math]の分だけ相対的に小さくなります。

すなわち、[math]m[/math]と高い相関関係
(正の相関でも負の相関でも良い)にある
[math]t[/math]が既知であるときに、[math]t[/math]を使って
[math]m^\star[/math]の期待値の推定量を求めることで、
[math]m[/math]の期待値の推定量を効率よく推定することができます。

See Also

posted by genki genki on Sat 19 Jul 2008 at 02:08 with 0 comments

イベントのお知らせです。

EGSR 2008の採択論文が出揃ってきたのを受けて、
OoO(=オフラインレンダラ野郎のためのオフラインレンダラについて議論するオフライン会)の第三回が開催されます。

OoO 第三回 : EGSR08 祭り

オフラインレンダラ野朗の皆様は奮ってご参加ください。

posted by genki genki on Fri 18 Jul 2008 at 04:30 with 0 comments

Kagemushaを使って、スコープを汚さないDSLスタイルのinitialize
メソッドを提供する方法を紹介します。

ruby>>
require 'rubygems'
require 'kagemusha'

class Foo
def initialize(&block)
bar = nil # default value
meta = eval('class << self; self end', block.binding)
Kagemusha.new(meta) do |kage|
kage.def(:bar){|bar|} # substitution
end.swap(&block)
@bar = bar
end
end

def bar(x); puts x end

foo = Foo.new do
bar 'bar'
end

puts foo.inspect # => #<Foo:0xb7c03de0 @bar="bar">
bar "hello!" # => hello!
<<--

bindingのコンテクストからメタクラスを取得し、
Kagemushaを使って限定的にbarメソッドを置き換えています。
Foo.newのブロック内から抜けると、
barの呼び出しはグローバルスコープのbarを呼んで、
"hello!"が出力されます。

この方法は、initialize以外にも、
ブロックを受けるインスタンスメソッド全般に利用できます。
例えば、以下のようなコードで、一時変数t
の存在が気になる場合などですね。

rails>>
create_table do |t|
t.string :foo
end
<<--

posted by genki genki on Thu 17 Jul 2008 at 18:41 with 1 comment

autotestでall_good時にrerun_all_testsをしないようにする
の改良版です。
handle_resultsメソッドの実装の変化を、
なるべく吸収できるような書き方に変えました。
~/.autotestに書いておくと良いかもしれません。

ruby>>
class Autotest
alias_method :handle_results_old, :handle_results
undef_method :handle_results

def handle_results(*args, &block)
handle_results_old(*args, &block)
self.tainted = !self.files_to_test.empty?
end
end
<<--

posted by genki genki on Tue 15 Jul 2008 at 21:52 with 0 comments

ちょっと前にこんな記事(モバイル端末でプログラムを書ける日は来るか)を書いていたのですが、
iphoneの日本語入力のインターフェイスについて説明してる動画を見て、
可能性を感じました。

1方向へのスライドだけでは難しそうだけど、各種コマンドを
↑→↓→みたいに指を離すまでの
ストロークにマップしたら相当便利になりそう。
iphoneにおけるVim的な何かが生まれる気がした。

posted by genki genki on Tue 15 Jul 2008 at 21:13 with 4 comments

tridentは、
tail -f log/development.logautotestscript/console
を一枚の端末上で同時に実行するRailsプラグインでした(trident: tail -f, autotest and script/console at once参照)

ほぼ全てのRailsプロダクトに入れていたのですが、
毎回プラグインインストールするのが面倒になってきたので、
Gem化してGitHub上でリリースしました。

使い方ですが、RAILS_ROOTで以下のコマンドを実行します。

pre>>
% trident
<<--

すると色々立ち上がって script/console のプロンプトが出ます。
autotestのCtrl+Cをする代わりに、以下のコマンドを実行します。

ruby>>

Trident.reload
<<--

終了する時はexitでOKです。

See Also

posted by genki genki on Mon 14 Jul 2008 at 14:05 with 0 comments

現在使っているConnectionアダプターについて、
Migrationで利用可能なデータタイプを調べる方法のメモ。

rails>>
ActiveRecord::Base.connection.native_database_types.keys
=> [:boolean, :date, :binary, :datetime, :string, :integer, :decimal, :primary_key, :time, :float, :timestamp, :text]
<<--

posted by genki genki on Mon 14 Jul 2008 at 03:24 with 0 comments

ブラックボックスなシステムを間に挟んで caller と callee
間で通信を行なう
Wormholeのバージョン0.1.2
をリリースしました。

新しい機能

  • Named wormhole: ネストしたWormholeの呼び出しに対して、名前を付けて区別することができるようになりました
  • Syntax constraint: catchブロックの直後にreturnメソッドが呼ばれていない場合に例外を投げるようにしました
    ruby>>
    w = Wormhole.catch do
    end #=> Wormhole::LateReturnError

(snip)
w.return

Worrmhole.catch do
end.return # => OK
<<--

ついでにWormholeの使用例を。

app/controllers/foo_controller.rb

rails>>
require 'wormhole'
class FooController < ApplicationController
def index
Wormhole.catch do
render :action => 'index'
end.return do |result|
result[:html] = "Hello, world!"
end
end
end
<<--

app/views/foo/index.html.erb

rails>>
<% Wormhole.throw do |result| %>
<%= result[:html] #=> 'Hello, world!' %>
<% end %>
<<--

Viewのコードから一端Controllerのコードに戻って、
またViewに戻って結果を表示しています。

このように、おいそれとは変更できないようなフレームワークのコードを跨いで、呼び出し側と呼び出し元の間で情報のやり取りを行なう事ができます。

posted by genki genki on Sat 12 Jul 2008 at 03:08 with 0 comments

D言語やPythonのように、複素数リテラルが欲しかったのですが、
無かったのでそれっぽい動きをさせるようにNumeric#iを定義してみました。

numeric_i.rb

ruby>>
require 'complex'

class Numeric
def i
self * Complex::I
end
end
<<--

これだけです。あとは以下のようにして使います。

ruby>>
require 'numeric_i'

1 + 1.i #=> Complex(1, 1)
(Math::E ** (Math::PI.i)).real #=> -1.0
<<--

(自分が)簡単に使えるように、GitHubでGemを作っておきました。
利用する場合は以下の手順で導入できます。

pre>>
gem sources -a http://gems.github.com
sudo gem install genki-numeric_i
<<--

名前空間のお陰で、シンプルなGemも気軽に公開できて良い時代ですね。

See Also

posted by genki genki on Thu 10 Jul 2008 at 20:15 with 0 comments

昔は違った気がするのですが、手元の環境のautotest(ZenTest-3.10.0)とRSpec-1.1.4を使った状態で、テスト中に一度例外が発生した後に、全てのテストをgreenにすると、全てのテストがもう一回全部実行されるという現象が起きています。

全部テストを実行するのは大変なので、とりあえず、.autotest
でパッチを当てて回避しました。

ruby>>
class Autotest
alias_method :handle_results_old, :handle_results
undef_method :handle_results

def handle_results(results)
failed = results.scan(self.failed_results_re)
completed = results =~ self.completed_re

self.files_to_test = consolidate_failures failed if completed

color = completed && self.files_to_test.empty? ? :green : :red
hook color unless $TESTING

#self.tainted = true unless self.files_to_test.empty?
self.tainted = !self.files_to_test.empty?

end
end
<<--

L14-15行目が修正箇所です。

posted by genki genki on Sun 6 Jul 2008 at 11:41 with 0 comments

メモもかねて。

MacBookにRailsの自動テスト環境を構築した

RAILS_ROOTでautotestを実行。起動時に全部のテストを実行するのでちょっとだけ重くなるかもしれません。それ以降はテストファイルやモデル、コントローラファイルなどを修正する度に該当のテストが走ります。

autotestを-fオプションを付けて立ち上げると、Fast startモードになり、最初に全部のテストを実行しなくなります。

posted by genki genki on Sun 6 Jul 2008 at 10:47 with 0 comments

KagemushaでActiveRecordのfindなどのクラスメソッドをswap
しようとすると、

pre>>
singleton method bound for a different object (TypeError)
<<--

というエラーが発生するという問題がありました。

このままでは困るので、とりあえず動くようにしてみました。
Unboundにしなければ問題は起こらないと思ったので、
instance_methodの代わりにalias_methodを使っています。

kagemusha_core_ext.rb

ruby>>
require 'uuidtools'

class Kagemusha #:nodoc:
def swap #:nodoc:
original_class_methods = {}
original_instance_methods = {}

@class_methods.each { |name, proc|
  if proc
    begin
      # replace method
      #method = @meta.instance_method(name)
      method = random_name
      @meta.instance_eval { alias_method method, name }
      @meta.instance_eval { define_method(name, proc) }
      original_class_methods[name] = method
    rescue NameError
      # insert method
      @meta.instance_eval { define_method(name, proc) }
      original_class_methods[name] = false
    end
  else
    begin
      # remove method
      #method = @meta.instance_method(name)
      method = random_name
      @meta.instance_eval { alias_method method, name }
      @meta.instance_eval { undef_method(name) }
      original_class_methods[name] = method
    rescue NameError
      # nop
    end
  end
}

@instance_methods.each { |name, proc|
  if proc
    begin
      # replace method
      method = @klass.instance_method(name)
      @klass.instance_eval { define_method(name, proc) }
      original_instance_methods[name] = method
    rescue NameError
      # insert method
      @klass.instance_eval { define_method(name, proc) }
      original_instance_methods[name] = false
    end
  else
    begin
      # remove method
      method = @klass.instance_method(name)
      @klass.instance_eval { undef_method(name) }
      original_instance_methods[name] = method
    rescue NameError
      # nop
    end
  end
}

return yield

ensure
original_class_methods.each { |name, method|
if method
# replace method
#@meta.instance_eval { define_method(name, method) }
@meta.instance_eval { alias_method name, method }
@meta.instance_eval { undef_method method }
else
# remove method
@meta.instance_eval { undef_method(name) }
end
}
original_instance_methods.each { |name, method|
if method
# replace method
@klass.instance_eval { define_method(name, method) }
else
# remove method
@klass.instance_eval { undef_method(name) }
end
}
end

private
def random_name
[UUID.random_128].pack("m").tr("=\n", '')
end
end
<<--

posted by genki genki on Sun 6 Jul 2008 at 02:28 with 2 comments

メソッドやProcの内部で継続(Continuation)を実行した後に、
そのメソッドの戻り値がどうなるのか理解があやふやだったので実験。

前準備。
ruby>>
a = nil
foo = proc{callcc{|a|}; 1}
bar = proc{foo.call; 2}
baz = proc{a.call; 3}
<<--

実験開始。

ruby>>

foo.call
=> 1

baz.call
=> 1

bar.call
=> 2

baz.call
=> 2
<<--

なるほど。

posted by genki genki on Sat 5 Jul 2008 at 04:05 with 0 comments

テストのC0カバレッジを上げるために、
何度もrcovを手で実行していたのですが、
テストの数が多くなってくると非常に時間がかかって面倒なため、
自動化するRakeタスクを作りました。

ruby>>
namespace :rcov do
desc 'Automate rcov'
task :auto do
interval = (ENV['INTERVAL'] || 10).to_f
org_path = File.join(RAILS_ROOT, 'coverage', '*')
pub_path = File.join(RAILS_ROOT, 'public', 'coverage')
sh "mkdir -p #{pub_path}"
loop do
Rake::Task['spec:rcov'].execute nil
sh "cp -Rf #{org_path} #{pub_path}"
sleep interval
end
end
end
<<--

使い方はRAILS_ROOTで以下のコマンドを実行するだけです。

pre>>
% rake rcov:auto INTERVAL=10
<<--

指定した時間間隔(秒)ごとにspec:rcovを実行します。
実行した結果はRSpecのデフォルトでは
RAILS_ROOT/coverageに出力されるので、これを
public/coverageに上書きコピーしています。
あとは、ブラウザで/coverageを見ればOKです。

public/coverageは間違ってデプロイしないように.gitignoresvn:ignoreに登録しておきましょう。

posted by genki genki on Sat 5 Jul 2008 at 03:53 with 0 comments

ちょっと必要に駆られて、
Wormhole
というライブラリを書きました。

350px-Worm3.jpg

インストールはGitHubから行えます。

pre>>
sudo gem sources -a http://gems.github.com
sudo gem install genki-wormhole
<<--

メソッドの内部を実行中に、呼び出し元に一旦処理を戻し、
中断した場所から処理を継続する機能を提供します。

例えば、以下のようなプログラムに対して、

ruby>>
require 'rubygems'
require 'wormhole'

def foo
puts "foo"
Wormhole.throw :foo => 'hello' do |data|
puts data[:foo]
end
puts "bar"
end

Wormhole.catch do
foo
end.return do |data|
puts data[:foo]
data[:foo] = 'world!'
end
<<--

結果として、以下のような出力を得ます。

pre>>
foo
hello
world!
bar
<<--

処理を中断したいところで Wormhole.throw を呼び出して、
外側から Wormhole.catch で受け止めます。
catchが完了したら、Wormholeオブジェクトが返るので、
returnで中断箇所に戻ります。
Wormhole.throw はHashを受け渡すことができます(省略可能)。
また、catchブロックとreturnは上記の例のように続けて記述します。
catchの戻り値を適当な変数に代入して、後でreturn
を呼び出すことも可能ですが、その場合、catchを抜けた直後から
returnを呼ぶまでの区間が二度実行されてしまいます
(この辺が最初に例外を使って実装してた理由ですね)

中断箇所から処理を再開するために callcc を使っています。
callccは面白いですね。

更新履歴

  • 2008/7/4 例外処理をやめてthrow/catchを使うようにしました。それにあわせて本文を修正しました。
posted by genki genki on Thu 3 Jul 2008 at 21:08 with 5 comments

以前笹田さんに、procのソースが見たいとお願いしてみたことがあったのですが、
それをRubyコードレベルで実現するライブラリを見つけたので紹介します。

proc_source.rb

I wrote this a while ago and it works by extracting a proc's origin file
name and line number from its .inspect string and using the source code
(which usually does not have to be read from disc) -- it works with
procs generated in IRB, eval() calls and regular files. It does not work
from ruby -e and stuff like "foo".instance_eval "lambda {}".source
probably doesn't work either.

オリジナルはメールの添付ファイルとしてくっついているので、ソースを見たい場合は
こちらから見るといいかもしれません。

使い方はこんな感じです、

ruby>>
code = proc{puts "Hello World"}
puts code.source #=> puts "Hello World"
<<--

これは久々に面白いものを見た気がします。

posted by genki genki on Thu 3 Jul 2008 at 13:33 with 0 comments

長い時間がかかるテストを実行してる間に。
もはやテストがない開発なんて考えられないけれど、
テストの実行時間が昔のコンパイル時間のように感じられます。

ちょっと前にデスクトップPCがPCの主流をノートPCに譲ったように、
iPhoneのようなモバイル端末がノートPCに取って代わるのは時間の問題であるように思います。
このような世代交代は、かつて人類が何度も経験してきたことであり、
ことコンピュータに関する限り、プログラマーという人種は最先端のデバイスを使いこなしてきたのですが、今回の大波を乗りこなすのはちょっと大変なんじゃないかと思っています。

モバイル端末の小さなキーボードや、iPhoneのようなソフトウェアキーボードにしても、どうにもこうにもプログラムを書くには不便すぎるのです。
プログラムを書くための環境は、デバイスの進化の本流から零れ落ちてしまうのでしょうか。

その昔、プログラマーがパンチカードを捨てて、キーボードによるプログラミングを覚えて以来、長いことお世話になってきたキーボードが、
プログラマーを椅子に縛り付ける鎖となってしまうのかもしれません(ノートPCがあれば多少は動けるでしょうが、iPhoneの機動性とは比べるべくもないですね)

そうならないようにするためには、モバイルキーボードに特化した言語を考える事も意味があるかもしれません。例えば、10個のアルファベットからなる英語のサブセットみたいなものを考えたら良いでしょうか?(Brainf*ckよりもっとフレンドリーなものを希望)
それとも記号をなるべく使わないプログラミング言語を考えたら良いでしょうか。

あるいは、キーボードではない入力方法でコーディングをする事を考えるべきでしょうか。図形を並べるようなプログラミング手法をGUIで行うようになるのでしょうか。

はたまた、プログラムを作るためのデバイスと、プログラムを使うためのデバイスは、永久に袂を分かつ事になるのでしょうか。

posted by genki genki on Mon 30 Jun 2008 at 18:14 with 0 comments
Contents rssrss
光ファイバーを二次元振動させて走査するAR用ディスプレイ
因果の取り違え
Swift2's defer for CoffeeScript
mongodb-3.0からcreateIndexのdropDupsが無くなったらしい
mongodb-3.0以降のWiredTigerの設定を動的に変更する方法
一般楕円の高速生成アルゴリズムへの道標
farro mantecatoのレシピ
Droonga関連の記事のまとめ
RuntimeErrorの特定のメッセージに限定してrescueする方法
jQueryでscriptタグを実行せずにappendする
Tags
memorubyrailstesttipsblogcallcccggemhelpmathお知らせautoautotesteventgitiphonelatexliblibrary
Comments rssrss
瀧内元気 瀧内元気: MacOS版は以下にあります genki/ViMouse 01/16 05:40
dsjf dsjf: https://gist.github.com/6bf1bf2c3cbb5eb6e7a7 これでも出... 01/08 23:23
瀧内元気 瀧内元気: おお、チェックしてみます。thx! 12/24 05:23
overisland overisland: Reeder for iPhone もこの UI を実装していますね。 12/24 05:13
瀧内元気 瀧内元気: その情報は見たのですが、以下のサイトによると、現在はまた必要になってるっぽいんですよね。 http:... 12/01 12:20
tkawa tkawa: http://devcenter.heroku.com/articles/rails31_herok... 12/01 10:47
瀧内元気 瀧内元気: どもー。いまはgithubに置いてあります https://github.com/genki/irb... 07/10 08:31
ともち ともち: こんにちは! すばらしいプログラムをありがとうございます。しかし、merbiのドメイン、切れているみ... 07/10 02:30
Services from s21g
YOMU Web小説リーダー
YOMUは、Web小説の読み上げに特化したiPhoneアプリです。
補助探
公開されている補助金・助成金情報を集約し、条件に合う制度を探しやすくするサービスです。
jotter.me
個人開発者のためのホスティング一体型ノートサービス
ハンドミラー
iPhone向けの手鏡アプリ
ツイプロ(twpro)
Twitterプロフィールの高速検索エンジン