忘れたときに備えた記録

トップ 最新 追記
2005|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|11|12|
2009|01|02|03|04|05|06|10|12|
2010|06|07|08|12|
2011|07|09|
2012|09|11|
2013|02|03|09|
2015|10|11|
2016|01|08|11|
2017|02|08|10|
2018|11|

2007-10-02(Tuesday)

RailsでSimpleLaTeX

MathMLライブラリではMathML::Scanner というクラスをLaTeX数式の読み取りに使っている。これはStringScannerを継承したもので、checkメソッドやscanメソッドをオーバーライドし、元のメソッドは_check等にaliasしている。そして、オーバーライド版のcheckメソッドで_checkメソッドを呼び出したりしている。

ところで、Rails で MathML::Util::SimpleLaTeX を使おうとするとmath_ml.rbが2回requireされてしまう。 この際、aliasが2回実行され、結果として同じオーバーライド版checkの中で、オリジナルのcheckを呼ぶつもりで、オーバーライド版のcheckを呼んでしまい、結果としてSystemStackErrorが発生してしまった。

と言うわけで、この問題を解決したものが http://svn.hinet.mydns.jp/trunc/math_ml/ から取得できます。パッケージングは後でします。

Tags: MathML

MathMLライブラリとREXML

ちなみにこの問題は、パスつきでrequireしたとき(require "../lib/math_ml" とか)とパス無しでrequireしたとき(require "math_ml")したときとで、結果として同じファイルを指定しているにもかかわらずrequireメソッドの方でそれを認識していないのが原因で、Ruby 1.8.6まででは発生する。

さっき試した所、Ruby 1.9ではこの問題が解決していたので、今回行った修正なしでも問題無く動作した。んが、1.9だとMathMLライブラリの方のテストに失敗してしまう。どうも、REXMLの挙動が微妙に変わったのが原因らしい。

そんなわけで、もうREXMLを使うのをやめて EimXMLだけを使うようにしようかと考えているのですが、そうなって困る人ってどなたかいます?

TortoiseHG

いつの間にかこんなモノが公開されていた。TortoiseSVNのMercurial版! Windows用GUIクライアント!!

後でぜひ試そう

MercurialでIDキーワード

CVSやSubversionで使うような $Id$ などのキーワード展開の機能を、Mercurialは標準ではもっていない。

ただし、キーワードを使えるようにするためのプラグインがKeywordExpansionExtensionとして公開されている。

これはクライアント側にインストールして使うもので、リポジトリを公開するサーバー側にだけインストールしてクライアント側でpullしてもキーワード展開は行われない。ただし、サーバーのリポジトリをhgwebなどのcgiを通して表示した場合などにはキーワード展開が行われる。

クライアント側では、

$ hg kwshrink

とすることで、一時的にキーワード展開を無効化できる。再びキーワード展開を使うときには

$ hg kwexpand

とする。

Tags: メモ

2007-10-03(Wednesday)

Mercurialに移行

ソースファイルを管理するSCMを、SubversionからMercurialに移行しました。URLは

になります。

Tags: 開発版

2007-10-09(Tuesday)

Rake でテスト

今まで、Rakeを使ったテストは、次のような感じでやっていた。

TESTS = FileList["*_test.rb"]

def do_test(opts)
	opts << " -n #{ENV["N"]}" if ENV["N"]
	sh "ruby -I ../ -r test/unit #{opts}"
end

task :default do
	TESTS.each do |i|
		do_test i
	end
end

もうちょっと綺麗に書けないものかなと思っていたら、まさしくその為の機能がRakeに用意されていることをついさっき知った。

参考にしたのは Rake 経由でUsing the Rake Build LanguageRake -- Ruby Make

準備として、簡単なテストスクリプトを用意する。ただしこれは、実際にテストせずに、いくつかの環境情報を表示する。

sub/test1.rb

require "digest"
$g ||= []
$g << __FILE__

puts "------#{__FILE__}------"
puts "---lib---"
puts $:
puts "---required---"
puts $"
puts "---$g---"
puts $g

sub/test2.rb

require "stringio"
$g ||= []
$g << __FILE__

puts "------#{__FILE__}------"
puts "---lib---"
puts $:
puts "---required---"
puts $"
puts "---$g---"
puts $g

digestとstringioをrequireしているのは、ロード済みライブラリの変化を確かめるためだ。

で、テスト用のタスク。一番単純な書き方はこんな感じ。

task :default do
	require "rake/runtest"
	Rake.run_tests 'sub/*.rb'
end

結果は以下のとおり

(in /home/hiraku/tmp)
------./sub/test1.rb------
---lib---
/home/hiraku/lib/ruby
(中略)
.
---required---
rbconfig.rb
(中略)
rake/runtest.rb
---$g---
./sub/test1.rb
------./sub/test2.rb------
---lib---
/home/hiraku/lib/ruby
(中略)
.
---required---
rbconfig.rb
(中略)
rake/runtest.rb
---$g---
./sub/test1.rb
./sub/test2.rb
Loaded suite /home/hiraku/opt/gem/bin/rake
Started

Finished in 0.000146 seconds.

0 tests, 0 assertions, 0 failures, 0 errors

Rake.run_testsを使うやりかただと、全てのテストスクリプトを一度にロードして、まとめて実行している。だから、テストに本来不要なライブラリがrequireでロードされているし、グローバル変数も共有している。Railsのテストもたぶん同じ方法を使っていて、おそらくそれが原因で、

rake test

としてもエラーが出ないけど、

rake test:functionals

としてtest/functionalsのテストだけを実行するとエラーが出たりすることがある(最近、Railsのテストの出力が少し変わったので、もしかしたらこの問題は解決しているかもしれない)。

というわけで、次の方法。

require "rake/testtask"
Rake::TestTask.new("test1") do |t|
	t.test_files = 'sub/test1.rb'
end
Rake::TestTask.new("test2") do |t|
	t.test_files = 'sub/test2.rb'
end
task :test=>[:test1, :test2]

Rake::TestTask.new(task_name)でテスト用のタスクを作りそのnewメソッドブロックの中で実行するテストスクリプトを指定する。 スクリプトが増えると大変なのでDRYにしたがってこう直す。

require "rake/testtask"
FileList["sub/*.rb"].each do |i|
	Rake::TestTask.new do |t|
		t.test_files = i
	end
end

Rake::TestTask.newでタスク名を指定しない場合、全部 test という名前のタスクになって、上書きではなく追記されるので、

$ rake test

で sub/*.rb が全部実行される。

結果は以下のとおり

(in /home/hiraku/tmp)
------./sub/test1.rb------
---lib---
lib
/home/hiraku/lib/ruby
/usr/local/lib/site_ruby/1.8
/usr/local/lib/site_ruby/1.8/i486-linux
/usr/local/lib/site_ruby/1.8/i386-linux
/usr/local/lib/site_ruby
/usr/lib/ruby/1.8
/usr/lib/ruby/1.8/i486-linux
/usr/lib/ruby/1.8/i386-linux
.
---required---
digest.so
---$g---
./sub/test1.rb
------./sub/test2.rb------
---lib---
lib
/home/hiraku/lib/ruby
/usr/local/lib/site_ruby/1.8
/usr/local/lib/site_ruby/1.8/i486-linux
/usr/local/lib/site_ruby/1.8/i386-linux
/usr/local/lib/site_ruby
/usr/lib/ruby/1.8
/usr/lib/ruby/1.8/i486-linux
/usr/lib/ruby/1.8/i386-linux
.
---required---
stringio.so
---$g---
./sub/test2.rb

sub/test1.rbの適当なところに $stdin.read とでも書いて途中で止めて ps コマンドで調べると分かるけど、テストごとにRubyのサブプロセスが起動して実行される。だから、ロードされるライブラリもそれぞれのスクリプトがrequireしたものだけがロードされ、グローバル変数も独立している。


2007-10-12(Friday)

RubyForge

EimXMLとMathMLライブラリのgemを作って、RubyForgeに登録することにした。

前々からやってみようかなと思いつつも先伸ばしにしていたのだけど、先日MathMLライブラリに\bm命令(物理分野での、ベクトルを表すときに使われるフォントらしい)を追加するパッチを頂き、その折にgemでの公開をリクエストされ、とうとう決心した次第。

まずは、RubyGems パッケージの作り方 - rubyforge 登録まで - 川o・-・)<2nd lifeを参考にnewgemコマンドを試してみたが、Webページ用の雛型やLicense.txtなどの、当面は使わなそうなファイルが一杯できてしまい、ちょっと困った。

それで結局、

を参考に、最小限のファイルだけを含むようなgemパッケージの作成を目指すことにした。

で、さっそく

require "rake/gempackagetask"
spec = Gem::Specification.new do |spec|
	spec.name = "eimxml"
	spec.version = "0.0.1"
	spec.summary = "Easy IMplemented XML"
	spec.author = "KURODA Hiraku"
	spec.email = "hiraku.spam@hinet.mydns.jp"
	spec.homepage = "http://eimxml.rubyforge.org/"
	spec.files = Dir.glob("**/*")
	spec.test_files = Dir.glob("test/*.rb")
	spec.has_rdoc = true
	spec.rdoc_options
end

Rake::GemPackageTask.new(spec) do |pkg|
end

task :default

なんてRakefileを作って

$ rake gem
$ cd pkg
$ gem install eimxml-0.0.1.gem

とかして出来たgemをインストールしたら

Successfully installed eimxml, version 0.0.1
Installing ri documentation for eimxml-0.0.1...
File not found: lib

インストールは成功したがlibディレクトリがないってんで怒られてしまった。もしかしてと思って動作確認をしてみたら

$ ruby -rubygems test.rb
/home/hiraku/lib/ruby/rubygems/custom_require.rb:27:in `gem_original_require': no such file to load -- eim_xml (LoadError)
        from /home/hiraku/lib/ruby/rubygems/custom_require.rb:27:in `require'
        from test.rb:1

やっぱりダメっぽい。eimxml-0.0.1/libというディレクトリを作って、その下にeim_xml.rbのリンクを作ったらうまくいったので、やはりディレクトリ構成が悪いのだろう。

などを参考に、なんとか出来ないか調査中。

# というわけで頂いたパッチは、この問題が解決して(もしかしたらディレクトリ構成を変えて)から取り込ませていただきます。


2007-10-16(Tuesday)

ロードパスに追加されるディレクトリ

次のようなディレクトリ構成のパッケージを作るときの注意事項。

eimxml-0.0.1/
|-- Rakefile
|-- eim_xml
|   |-- assertions.rb
|   |-- parser.rb
|   `-- xhtml.rb
|-- eim_xml.rb
`-- test
    |-- Rakefile
    |-- assertions_test.rb
    |-- eim_xml_test.rb
    |-- parser_test.rb
    `-- xhtml_test.rb

ポイントは、require "eim_xml"でロードされたい eim_xml.rb が eimxml-0.0.1/のすぐ下に置いてあること。他の一般的なgemパッケージでは、eimxml-0.0.1/lib/の下に置くことになる。

やりかたは簡単で、先日のRakefileに次の記述を追加すれば良い。

	spec.require_paths = ["."]

これで、上に挙げたようなディレクトリツリーのパッケージを作ることが出来る。

でも、require "test/..."としたときに、eimxml-0.0.1/test/の下が検索パスに含まれてしまうので、このディレクトリ構成は良くないんじゃないかと思い始めた。やっぱ、ディレクトリ構成を変えてしまおう。

Tags: RubyGems

2007-10-23(Tuesday)

GEM公開!!

MathMLライブラリとこれが使用するXMLライブラリであるEimXMLのgemパッケージを作って、RubyForgeで公開し始めました。

名前がrequireするときと違って、アンダースコアなしになっています(プロジェクト名に'_'が使えないのには驚きました。ハイフンは使えるのに)。

もう少ししたら、

$ gem install -y mathml

でインストールできるようになるはずです。楽しみだなぁ

Tags: RubyForge
本日のツッコミ(全2件) [ツッコミを入れる]

_ t-nissie [bmパッチの採用ありがとうございます。 そして、RubyForgeからのgemのリリースおめでとうございます。 ge..]

_ hiraku [こちらこそ、ご愛顧ありがとうございます。 メールで要望のあった$a''$の件は、ちょっと忙しいので直には手を付けられ..]