Ruby win32ole 拡張モジュール覚え書き(5)

Win32OLE製作過程の目次へ

2つの宿題

Ruby の作者の まつもとゆきひろさんから

英語のドキュメントつけてね」
「method_missing の実装がRubyスクリプトになってるけど, 拡張モジュールは,全部 C で書くのが私の好み」

と言われました. ・・・宿題を出された生徒の気分です.^^;

世界を相手にしている Ruby には英語のドキュメントが必要だというのは 理解できます.素直にできの悪い生徒なりに頑張ることにしました. (英語は苦手です.・・・もっとも日本語も怪しいもんですが.)

method_missing の C による実装は,まつもとさんの好みというだけのようですので, 「そんなん知るか」と反抗しても良かったのですが, まつもとさんの好みとは別の理由で,C で書くことにしました.

C で全部書いておけば,

と考えたからです.

じゃあ何故最初から C で書かなかったのか? それは私が,method_missing を C で実装する方法がわからなかったからです.
難しく考えないで,他のメソッドを C で書く場合と同じように書けば良かったのでした. スクリプトで書いた method_missing を素直に,C に置き換えていけば, 実装できたのでわりと簡単でした.

スクリプトでメソッドを定義していくのと同じような感覚で 拡張モジュールをCで書けるところが Ruby のすごいところだと思います. (まつもとさんは,そのことも計算して Ruby の設計をしているに違いないと思います.)


0.0.2 リリース

WIN32OLE::new メソッドは,新規に OLE オートメーションサーバーを起動します. 起動中の OLE オートメーションサーバーにアクセスする手段がなかったので それを用意することにしました.WIN32OLE::connect メソッドです. 例によって Perl のソースコードを流用して(参考にして),実装しました.

と言う訳で英語のドキュメントを用意し,C言語で全部実装し, 新機能を1つ追加して,バージョン 0.0.2 をリリースしました.


またも失敗

相変わらず,Perl の OLE モジュールを使っている知人に, Ruby にも win32ole 拡張モジュールができたことを伝えたところ

名前付き引数は使える? 定数は使える?

と質問され,両方とも使えないと答えると知人は小さくガッツポーズをし, 「勝った。」と一言つぶやいたのでした. ・・・こうして私はまたしても知人を Ruby ユーザーにすることに失敗しました.


名前付き引数

Excel VBA などでは

'Sheet1 シートの後ろに 2枚シートを追加する.
Worksheets.Add(count:=2, after:="Sheet1")

というように名前付き引数を使ってメソッドを呼び出すことができます. 名前付き引数の良いところは,

というところです.

Perl では名前付き引数をハッシュを使って実現しています.

$Worksheets->Add({count=>2, before=>"Sheet1"});

Ruby の win32ole でも Perl に倣ってハッシュを使って実現することにしました.

worksheets.add({'count'=>2, 'before'=>"Sheet1"})

すべての引数にハッシュを使用できてもそのメリットはあまりないし, その割に実装が面倒だと考えて, 最後の引数にだけハッシュを指定できることにしました.

worksheets.add({'count'=>2, 'before'=>"Sheet1"}) はOK.
worksheets.add("Sheet1", {'count'=>2}) もOK.
worksheets.add({'count'=>2}, {'before'=>"Sheet1"}) は駄目.

ハッシュ

一応,名前付き引数の実装はできていたのですが, C言語レベルでの Ruby のハッシュの扱い方に, ちょっと自信がなかったので質問しました.

回答は

ハッシュの要素を1つずつ取り出して何か処理するには, rb_iteraterb_each を 組み合わせを使う.

というものでした.

私は,違う関数を使って実装していました. ですが,まつもとさん推奨の実装方法に従っておいた方が, Ruby 本体のバージョンアップにも対応しやすいだろうと考えて rb_iterate と rb_each を使って実装しなおしておくことにしました. (基本方針4

やっぱり,聞いてみないとわからないもんです.


cygwin32

cygwin32版 Rubyでも, win32ole 拡張モジュールが動いたという非常に嬉しい情報がありました. (わたなべさんに感謝.)

正直言って私は,cygwin32版では,動作させるのが無理ではないかと 思っていました. cygwin32 B19のヘッダーファイルには,Invoke など win32oleで使っている関数の宣言が無かったからです.

lcc-win32 のヘッダーファイルを使って動くようにしたそうです.


サンプル

Excel が無くても動くサンプルをつけて欲しいという要望がありました.

WSH が使える環境や Internet Explorer Ver 4.0 以降がインストールされている環境だと いろいろサンプルを作れそうです. ですが,結局,中田さん提供の Internet Explorer を使ったサンプルを流用させて頂くことにしました. このサンプルの方がより多くの環境で動作するだろうと考えたからです.

ついでに名前付き引数の例としてもう一つ excel3.rb を追加しました. (結局 Excel を使う私.^^;)


0.0.3 リリース

ということで,0.0.3 をめでたくリリースしました. ですが,自分では一度も実用で win32ole を使ったことがないのでした.


Win32OLE製作過程の目次へ