[ruby-list:39073] Ruby1.8のWIN32OLEで-wのとき

From: Takashi Kanai <kanai@...4u.or.jp>
Date: 2004-01-24 14:25:09 UTC
List: ruby-list #39073
 金井です。

 Ruby1.8で -w を付けてWIN32OLEを使用すると、帰って来なくなるという
現象が出ています。
 一番下に検証用のスクリプトを置きました。
 Excelのファイルを開いてセルを読み出すという単純なものです。

 これは 1.6.8 では問題なく動作しますが、1.8では問題が生じます。
 コマンドプロンプトから Rubyスクリプト として実行した場合には
たくさんのワーニングメッセージが表示されますが、結果には問題は
ありません。ところが、これを CGI としてブラウザから実行すると、
途中(セルの読み出しの所)で制御が戻って来なくなります。
 その時、タスクマネージャを見ると、CPUはゼロ%で、メモリ使用量
にも特に変化はありません。
 調査の結果、Ruby1.8以上で -w オプションを付けた場合の現象である
ことが分かりました。-W2 または $VERBOSE=true でも同様です。
 なお、1.8.0/1.8.1とも現象は同じです。
  +-----------------------------------------------------+
 | -w 無し |  1.6  | コマンド |  ○                    |
  |         |       | CGI      |  ○                    |
  |         |-------------------------------------------|
 |         |  1.8  | コマンド |  ○                    |
  |         |       | CGI      |  ○                    |
 -------------------------------------------------------
 | -w 有り |  1.6  | コマンド |  ○                    |
  |         |       | CGI      |  ○                    |
  |         |-------------------------------------------|
 |         |  1.8  | コマンド |  △  ワーニングが出る  |
  |         |       | CGI      |  ×  帰って来なくなる  |
 +-----------------------------------------------------+
環境は
 Windows 2000(SP4)
 Apache 2.0.48 (Win32)
 IE 6.0
 ruby-1.6.8-20030515-i586-mswin32.zip
 ruby-1.8.0-20030812-i386-mswin32.zip
 ruby-1.8.1-i386-mswin32.zip  (2003-12-25 リリース版)

ワーニングメッセージは
-----------------------------------------------------------------
warning: class variable ARGV of Object is overridden by WIN32OLE
-----------------------------------------------------------------
というもので、
  (a) books.worksheets( 1 )
  (b) area.rows( y )
  (c) row.cells( 1, x ).text
の3カ所を通る度に出力されます。例えば5列のXLSを与えると、行ごとに
area.rowsで1つ、row.cellsで5つのワーニングが出ます。
 何種類かのExcelファイルを食わせてみたところ、上記の3種類の呼び出し
の累計が 591番目になった時の row.cells 呼び出しで帰って来なくなる、
ということが分かりました。

  Excelの列数  止まる場所[y,x]   呼び出し回数 (a)+(b)+(c)
  ------------------------------------------------------
           5   [99, 1]           1+99+(99-1)* 5+ 1 = 591
          10   [54, 6]           1+54+(54-1)*10+ 6 = 591
          21   [27,17]           1+27+(27-1)*21+17 = 591
          26   [22,22]           1+22+(22-1)*26+22 = 591
  ------------------------------------------------------

テスト用の CGI は以下のようになっています。
ちなみに $LOG うんぬんは、私製のデバッグ用のルーチンで、
デバッグ用の窓にメッセージを表示するようになっており、
ここでは、どこで止まったかを調べるために使用しています。
-----------------------------------------------------------
#!/usr/local/bin/ruby.exe -Ks -w
#---- この -w を取れば現象は出ない ----
require 'win32ole'
require '../script/rx-log.rb'            # デバッグ用
$LOG = RxLog.new                         # デバッグ用
$LOG.start_socket( "localhost", 10003 )  # デバッグ用

module Excel
end
puts "Content: text/html"
puts
puts "<HTML><BODY><TABLE border>"
excel = WIN32OLE.new( 'Excel.Application' )
begin
  WIN32OLE.const_load( excel, Excel )
  excel.visible = false
  excel.displayAlerts = false
  books = excel.workbooks.open({
    'filename' => "g:\\test1.xls",
    'readOnly' => true
  })
  sheet = books.worksheets( 1 )      # (a) ワーニングが出る
  area = sheet.usedrange
  rows = area.rows.count
  cols = area.columns.count
  (1..rows).each do | y |
    s = "<TD>#{y}</TD>"
    row = area.rows( y )             # (b) ワーニングが出る
    (1..cols).each do | x |
      $LOG << "//// [#{y},#{x}]"     # デバッグ用
      t = row.cells( 1, x ).text     # (c) ワーニングが出る
      $LOG << "//////// #{t}"        # デバッグ用
      s += "<TD>#{t}</TD>"
    end
    puts "<TR>#{s}</TR>"
  end
ensure
  excel.quit
  GC.start
end
puts "</TABLE></BODY></HTML>"
-----------------------------------------------------------

--
金井 隆 (KANAI Takashi)
kanai@nn.iij4u.or.jp



In This Thread

Prev Next