Ruby on Windows (1)

目次へ

Rubyの見分け方

2000-09-22 改訂

Windowsの環境で、ruby が cygwin 版なのか mswin32 版なのか Mingw版なのか見分けるには

ruby -v

を実行します.

ruby 1.6.1 (2000-09-22) [i386-cygwin]
ruby 1.6.1 (2000-09-22) [i586-mswin32]
ruby 1.6.1 (2000-09-22) [i386-mingw32]

それぞれ上から Cygwin版 mswin32版 mingw32版ということになります。


共存方法

2000-09-22改訂

私は,2つの Ruby を共存させるために

Cygwin版Rubyのruby.exeファイルの名前をrubycw.exe
mingw32版 Rubyのruby.exeファイルの名前をruby.exe

と変更して使っています.
(私は主にmingw32版を使っているのでmingw32版の名前を変更してません。mswin32版はたまにコンパイルするだけでろくに使っていません。)

さて,このとき問題になるのが,拡張ライブラリの共存です.

置くようにしましょう.そうすれば,何の問題もありません.

具体的にどこにおけば良いかは,プロンプトから

ruby -e 'puts $LOAD_PATH'

と実行すればわかります.

Ruby 1.6.1 では

cygwin32版 の実行結果は

/USR/LOCAL/lib/ruby/site_ruby/1.6/i386-cygwin
/USR/LOCAL/lib/ruby/site_ruby/1.6
/USR/LOCAL/lib/ruby/site_ruby
/USR/LOCAL/lib/ruby/1.6/i386-cygwin
/USR/LOCAL/lib/ruby/1.6
.

となりますので,

\usr\local\lib\ruby\1.4\i386-cygwin

に cygwin32版 Ruby 用の拡張モジュールの DLL ファイルを置けば良いでしょう.

mingw32版 の実行結果は

D:/USR/LOCAL/lib/ruby/site_ruby/1.6/i386-mingw32
D:/USR/LOCAL/lib/ruby/site_ruby/1.6
D:/USR/LOCAL/lib/ruby/site_ruby
D:/USR/LOCAL/lib/ruby/1.6/i386-mingw32
D:/USR/LOCAL/lib/ruby/1.6
.

となりますので,

\usr\local\lib\ruby\site_ruby\1.6\i386-mingw32
\usr\local\lib\ruby\1.6\i386-mswin32

のどちらかにmingw32版Ruby用の拡張ライブラリのDLLファイルを置けば良いでしょう.


rubyw.exe

cygwin32版 Ruby には,ruby.exe の他に rubyw.exe が含まれています. これは,Explorer からスクリプトのファイルのアイコンを直接ダブルクリックして 実行したい時に使うようです.

拡張子が ".rb" のファイルを rubyw.exe に関連づけておきます. マウスで,xxx.rb のファイルをダブルクリックして実行すると, DOSプロンプト(コンソールウィンドウ)を 表示することなくスクリプトを実行できます. DOSプロンプトを表示する必要のない, tk 等を使ったGUIのスクリプトを実行するときには, この方法が使えます. ( DOSプロンプトを必要とするスクリプトでは試さないでください.

実際には,DOSプロンプト(コンソールウィンドウ)を 必要とするスクリプトも多いと思います. ですから, DOSプロンプトを必要としないスクリプトだけを xxx.wrb と名前を変更して ".wrb"を rubyw.exe に関連づけておいた方が良いかも知れません. そうしておいて, xxx.rb は DOSプロンプトから ruby.exe を使って実行し, xxx.wrb は マウスのダブルクリックで rubyw.exe を使って実行するようにします.

実は,私は,rubyw.exe を確認のために1度しか使ったことがないので, この程度の使い道しか知りません.


Win32OLE を使う場合のテクニック

Excel の VBA などでは,'.' の数を減らした方が速く動作します. これは,Ruby の Win32OLE を使ったスクリプトの場合でも同じです. 例えば,

application = WIN32OLE.new('Excel.Application')
application.visible = TRUE
workbook = application.Workbooks.Add()
worksheet = workbook.Worksheets(1)
worksheet.Range("A1").value = 1
worksheet.Range("A2").value = 2
worksheet.Range("A3").value = 4
worksheet.Range("A4").value = 8

と書くのと

application = WIN32OLE.new('Excel.Application')
application.visible = TRUE
workbook = application.Workbooks.Add()
workbook.Worksheets(1).Range("A1").value = 1
workbook.Worksheets(1).Range("A2").value = 2
workbook.Worksheets(1).Range("A3").value = 4
workbook.Worksheets(1).Range("A4").value = 8

と書くのとでは,前者の方が速く動作します.

workbook.Worksheets(1).Range("A1").value = 1

の workbook.Worksheets(1) では workbook オブジェクトに対する Worksheets メソッドが呼び出され, このとき Win32OLE の内部では,

  1. 'Worksheets' という名前から OLEの GetIDsOfNames 関数を使って ID を求める.
  2. 求めたIDを指定してメソッドを実行する.

という処理を実行しています.

workbook.Worksheets(1)というメソッド呼び出しがある度に, この2つの処理が内部で動いている訳です. ですから,できるだけ '.'の数を減らして,メソッド呼び出しを少なくした方が, GetIDsOfNames 呼び出しもしなくて済むので速く動く訳です.

1回目だけ,GetIDsOfNames を使って 2回目以降は, ハッシュを使った方が速いかなと思ったりしています. つまり,

workbook.Worksheets(1) というコードが最初に出て来たときだけ GetIDsOfNames を使って ID を求めて 'Worksheets' と ID をハッシュで保持しておく. 2回目以降は,ハッシュを検索して,GetIDsOfNames を使わないようにする.

こんな感じの方が,速く動くようになるかなと思いながら,まだ試していません. 作者の怠慢です.

Ruby 本体については,このような GetIDsOfNames 関数を使っていませんし, 高速化の工夫もされているようですので, Win32OLE を使う場合ほど気にする必要はないでしょう.

長々と書きましたが ポイントは,'.' の数を減らして簡潔に書いた方が VBA でも Ruby の Win32OLE でも速く動くということです.


目次へ