[Ruby] Win32OLE 対応できるんだったら対応したいもの
その1。[ruby-talk:298615]に対応する。
その2。.NETで作られたOLEサーバー(?)のイベント通知に対応する。
確か、これは、EVENTSINK_GetIDsOfNames などをちゃんと実装しないといけなかったような気がする。
| 固定リンク | コメント (2) | トラックバック (0)
その1。[ruby-talk:298615]に対応する。
その2。.NETで作られたOLEサーバー(?)のイベント通知に対応する。
確か、これは、EVENTSINK_GetIDsOfNames などをちゃんと実装しないといけなかったような気がする。
| 固定リンク | コメント (2) | トラックバック (0)
その1。WIN32OLE_EVENT#off_event([arg])
WIN32OLE_EVENT#on_event([arg]) で設定したイベントハンドラを無効にしてイベントが通知されないようにする。
その2。WIN32OLE_EVENT#handler=
handlerオブジェクトを設定する。
class Handler
def navigateComplete(url)
puts url
end
def beforeNavigate(...)
...
end
...
end
ie = WIN32OLE.new('InternetExplorer.Application')
ev = WIN32OLE_EVENT.new(ie)
ev.handler = Handler.new
と書けるようになる。(PythonやPerlに近いスタイルで書けるようにする。)
WIN32OLE_EVENT#on_event で設定したコールバックと WIN32OLE_EVENT#handler で設定したコールバックが重なる場合、 WIN32OLE_EVENT#on_event を優先する。
| 固定リンク | コメント (0) | トラックバック (0)
bdata = WIN32OLE_VARIANT.new(bstring,
WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_ARRAY)
は
bdata = WIN32OLE_VARIANT.new(bstring,
WIN32OLE_VARIANT::VT_UI1|WIN32OLE_VARIANT::VT_ARRAY)
と書けると混乱しなくて済むか。
なんか設計間違えたような...
| 固定リンク | コメント (0) | トラックバック (0)
4. WIN32OLE_VARIANTクラスが追加された。
Win32OLEがOLEサーバー側の関数(メソッド)を実行するときに引数はすべて参照渡しで実行するようになってます。 ですが、値渡しを要求する関数(メソッド)も存在します。 そのとき、WIN32OLE_VARIANTクラスを使うことができます。
fso = WIN32OLE.new("Scripting.FileSystemObject")
shell = WIN32OLE.new("Shell.Application")
folder = shell.NameSpace(fso.getFolder(".").path)
item = folder.ParseName("temp.txt")
shortcut = WIN32OLE_VARIANT.new("ショートカットの作成(&S)")
item.invokeVerb(shortcut) # shortcutは値渡し
WIN32OLE_VARIANT.new メソッドは第二引数にVT_XXXを指定して、指定した型のWIN32OLE_VARIANTオブジェクトを生成することができます。 たとえば、Win32OLEは、デフォルトで文字列をVT_BSTR型に変換しますが、バイナリデータをそのままOLEサーバーの関数(メソッド)に 引数として渡したいときに困ります。1.8では、_invokeを使う方法が提供されていました。 1.9では、従来の方法の他、WIN32OLE_VARIANT.newメソッドを使う方法があります。
bdata = WIN32OLE_VARIANT.new(bstring,
WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_ARRAY)
として bstringの代わりにbdataを引数として使うことによってバイナリデータをそのまま渡すことができます。
1.9で Encoding が ASCII-8BIT ならバイナリだと見なしてよいのではないかという議論がありました。 今のところ、Win32OLEでは、Encoding が ASCII-8BIT な文字列が渡されてもバイナリという判断はしません。 VT_BSTR型に変換します。 ASCII-8BIT の String をバイナリとして扱いたいときも、明示的に WIN32OLE_VARIANT.new を使ってください。
| 固定リンク | コメント (0) | トラックバック (0)
とある事情があって、できれば見ることなく済ませたかったRubyのtrunkのeval.cのソースを 眺めて(ちらっと見て)いるんだけど、 rb_raise_jumpの中の
/* TODO: fix me */
って何だろう? もしかして何かがfixされるとWin32OLE側では何もしなくてもよくなるのかなあ。
| 固定リンク | コメント (0) | トラックバック (0)
簡単にできると思ったのに。 EVENTSINK_Invokeの中でCancelからDispIDを取得する方法がわからん。
簡単に実装できそうなのは、
{:return => 1, 5=> true}
のように何番目の引数の値を設定するかという書き方だけ。
...と思ったけど、ITypeInfo::GetNamesを使えば、DispID取得しなくてもいけそうだ。
| 固定リンク | コメント (0) | トラックバック (0)
event.on_event('BeforeNavigate') {|*args|
{:Cancel => true}
}
と書けるのがすっきりしていい気がしてきた。
event.on_event('BeforeNavigate') {|*args|
beforeNavigate(*args)
}
とメソッドを定義した場合には、メソッドの中で
def beforeNavigate(*args)
...
{:Cancel => true}
end
と書くか、
def beforeNavigate(*args)
...
{5 => true} # 5番目の引数に trueを設定して返す。
end
でよい。メソッドの実行結果を戻り値としてOLEサーバー側に返したい場合は、:return を使って
def beforeNavigate(*args)
{:return => true, 5 => true}
end
のように書く。
| 固定リンク | コメント (3) | トラックバック (0)
自分で作っといて、アレだけど、使いにくいな。 なんとかならんもんかと考えていたんだけど、on_eventのときでもHashを返すというアイディアはどうだろうか。
event.on_event('BeforeNavigate') {|*args|
beforeNavigate(*args)
}
と書いても
def beforeNavigate(*args)
outargs = []
outargs[5] = true
{:result => 1, :args => outargs}
end
とか、更にoutargsはHashでもいいことにして、
def beforeNavigate(*args)
{:result => 1, :args => {:Cancel => true}}
end
とできるとか...
| 固定リンク | コメント (0) | トラックバック (0)
Pythonでは、COCLASSを求めるようなことをしているみたい。 RubyのWin32OLEでもCOCLASSを探すことにした。
結果として次のようなのが動くようになった。
require 'win32ole'
ie = WIN32OLE.new('InternetExplorer.Application')
ie.visible = true
ev = WIN32OLE_EVENT.new(ie) # ここに注目。
ev.on_event(...){|*args|...}
これを書きながら考えていたのだが、やっぱり、まだ、ちょっと不完全な気がしてきた。 不完全な部分の修正はまた後程。
| 固定リンク | コメント (1) | トラックバック (0)
以下のスクリプトをruby 1.9.0(trunk revision 17942)で実行する。
equire 'win32ole'
ie = WIN32OLE.new('InternetExplorer.Application')
ie.visible = true
begin
tname = ie.ole_type.name
coclass = ie.ole_typelib.ole_classes.select {|k|
k.ole_type == "Class"
}.select {|k|
k.default_ole_types.select{|dt|
dt.name == tname
}.size > 0
}
coclass.each do |c|
puts "#{c.name}(#{c.progid}) => #{c.default_event_sources.inspect}"
end
ensure
ie.quit
end
実行結果は、
WebBrowser(Shell.Explorer.2) => [#<WIN32OLE_TYPE:DWebBrowserEvents2>] InternetExplorer(InternetExplorer.Application.1) => [#<WIN32OLE_TYPE:DWebBrowserEvents2>] ShellBrowserWindow() => [#<WIN32OLE_TYPE:DWebBrowserEvents2>]
となるので、なんとなく2行目から、DWebBrowserEvents2 が使えるんじゃないかと思うことができる。
もう一度、Pythonのソースを調べてみれば、DWebBrowserEvents2を省略できるようになるかも知れない。
| 固定リンク | コメント (0) | トラックバック (0)
あまり知られていないと思いますが、WIN32OLE_EVENTの第2引数は省略できます。 ですが、省略してうまくいく例を私は知りません。
WIN32OLE_EVENTもPerlを真似してソースを書いてます。 もしかして、ちゃんと真似できていないのかと思い、 InternetExplorerで試してみたところ、Perlでも省略すると動作しませんでした。
Pythonは指定しなくてもいいので、どうやっているかとちょっとソースを覗いてみたところ がしがしとタイプライブラリの情報を読んで第2引数に相当する情報を読み取っているみたいです。
まだ、ゴールは遠いのですが、手元のソースをいじったところ、 第2引数のヒントぐらいは出せるようなところまでなら行けそうな雰囲気です。
もうちょっと手元でテストしてみたいと思います。
| 固定リンク | コメント (0) | トラックバック (0)
3. WIN32OLE.codepageの動作が変わった。 Ruby m17n絡みで変わった点です。 まず、WIN32OLE.codepageの初期値は、1.8では、WIN32OLE::CP_ACPでしたが、1.9では、Encoding.default_externalに従って初期値が決まります。
また、1.8では、RubyのStringオブジェクトをOLEサーバー側に渡すときに、WIN32OLE.codepageを参照してUnicode(UTF-16LE)に変換して 渡していましたが、1.9では、StringオブジェクトのEncoding(String#encoding)を参照してUnicode(UTF-16LE)に変換するようになりました。
このため、1.9では、WIN32OLE.codepageの値が意味を持つのは、OLEサーバー側からStringオブジェクトを受け取るときです。 Stringオブジェクトを受けとるときに、WIN32OLE.codepageの値に従って変換されます。
たとえば、
# -*- encodinge:Windows-31J -*-
dict = WIN32OLE.new('Scripting.Dictionary')
dict.add("Windows31J", "あいう") # Windows-31Jの文字列 "あいう"をセット
puts dict["Windows31J"].encoding # => Windows-31
puts("あいう" == dict["Windows31J"]) # => true
WIN32OLE.codepage = WIN32OLE::CP_UTF8
puts dict["Windows31J"].encoding # => UTF-8
puts("あいう" == dict["Windows31J"]) # => false!!!
puts("あいう".encode("UTF-8") == dict["Windows31J"]) # => true
となります。
つまり、WIN32OLE.codepageの設定によっては、OLEサーバー側に渡した文字列のエンコーディングとは異なるエンコーディングの文字列をOLEサーバーから受け取ることになります。
WIN32OLE.codepageのこの動作は、将来、変更される可能性があります。 また、OLEサーバー側から受け取るときだけWIN32OLE.codepageが登場することから、WIN32OLE.codepageという名前が変わる可能性もあります。
| 固定リンク | コメント (0) | トラックバック (0)
1.8と1.9とでは、Win32OLEに違いがあります。 これまで、Win32OLEは互換性をできる限り保ちつつ改訂してきたのですが、 1.9では互換性を保っていないところがあります。
そろそろ、違いをちゃんと整理し始めた方がいいんじゃないかと思っています。 まだ、1.9での仕様を決め兼ねている部分もあるのですが...。 ちょっとずつ、気の向いたときに書いていこうかと思ってます。
変更点
1. WIN32OLE#[], WIN32OLE#[]= を使ったプロパティの設定、参照が1.9ではできない。
つまり、1.9では、
ex = WIN32OLE.new('Excel.Application')
ex['Visible'] = true
puts ex['Visible']
とは書けなくて、
ex = WIN32OLE.new('Excel.Application')
ex.Visible = true
puts ex.Visible
としか書けません。
2. 次のような書き方ができるようになった。
dict = WIN32OLE.new('Scripting.Dictionary')
dict.add("foo", "FOO")
puts dict["foo"]
dict["foo"] = "BAR"
puts dict["foo"]
これは、1.の変更の代わりに新たにできるようになったことです。
技術的に細かい話は、ここでは省略しますが、今まで、
xxxx.item("foo")
と書かなくてはいけなかったものが、運が良ければ、
xxxx["foo"]
とVBScriptライクな書き方ができるようになったということです。
従来通り、
xxxx.item("foo")
と書いても大丈夫です。
| 固定リンク | コメント (0) | トラックバック (0)
いや、もう、ホント、前からちょっと感じてたことなんですよ。 WIN32OLE_EVENTの実装というか設計というか、なんとなくダメだなと思ってた訳です。 特に、1.9は新たな機能を盛り込もうとして、もうなんかムリしちゃって...。
いや、まあ、ここだけの話ですけどね。
で、今、もう、設計そのものが間違ってたんではないかという気がしてしょうがないんです。 じゃあ、どういうのが正しいのかって聞かれると、全くもって答えられない訳です。
いや、まあ、ホント、ここだけの話にしといてください。
| 固定リンク | コメント (2) | トラックバック (0)
Ruby の StringをWin32OLE側で受け取るときには、encodingを参照するようにしてみた。 WIN32OLE.codepageは参照しません。 なんか問題があるかも知れないので、テストしてくれるチャレンジャーな人がいると嬉しいです。 若干、パフォーマンスが悪くなっているかも。
WIN32OLE.codepageが参照されるのは、WIN32OLE側から、RubyのStringを返すときだけになります。 WIN32OLE.codepageという名前は変更した方がいいような気がするんだけどいい名前が思いつきません。
| 固定リンク | コメント (0) | トラックバック (0)
タイミングが遅いですが...。
RubyKaigi 2008 でなかむら(う)さんと 話したんだけど、 1.9のcygwin版とかmingw32版は、テストが手薄らしいです。 (ひょっとしたら1.8もかも。) 特にcygwin版はebanさんも恐らく Linuxでクロスコンパイルしていると思われるので、テストはかなり手薄だと思われます。
Win32OLEのメンテナをやっている関係上、私は、cygwin版とmingw32版のmakeはするんだけど テストは、
make test-all TESTS=win32ole
しかやってませんでした。
(もっとも、mingw32版は、Cygwin上でgcc -mno-cygwin でコンパイルしているだけで、MSYS上ではないです。)
ということで気の向いた方は、configure の実行から make して、テストして何かあったら ruby-devとかにバンバン報告していただけると助かります。
ちなみに先日、私が報告したcygwinのmake testが失敗する件 (ruby-dev:35183)は いつの間にか修正されてました。
ちなみに、Win32OLEのテストは1.9では、できる限りOfficeとかに依存しないようになってます。 なので、Microsoft Officeがインストールされていない環境でもほとんどのテストができます。 (自分の開発環境にも、Microsoft Officeがインストールされていません。)
Officeに依存しているのは、多分wordの
wordApp.wordbasic.disableAutoMacros(true)
のテストです。 このスクリプトを通すために アドホックなことをやっていて(Perl Win32::OLEでも同じことをしている)、 今のところ、別のテストを作れないでいます。
あと、できれば、InternetExplorer(というかGUIなアプリ全般)にも依存しないようにしたいんだけど、 WIN32OLE_EVENTのテストをGUIなアプリなしで、どうやったら書けるのかわからないです。
| 固定リンク | コメント (0) | トラックバック (0)
Ruby 1.9での話。 Win32OLEヘビーユーザのみなさまへ質問。
Win32OLE から VT_UI1|VT_ARRAY なデータをRuby側に返す場合に1.8では、Arrayで 返しているのだけれど、Stringを返した方がいいでしょうか?
1. Win32OLEでは、Array.pack("C*") でASCII-8BITなStringに変換してから返す。
2. Win32OLEでは、従来通り、Arrayのままでよい。
データベースからバイナリデータを検索するときなどに遭遇する場面だと思います。 どっちがよいですか?
| 固定リンク | コメント (0) | トラックバック (0)
RubyKaigi 2008 で複数の人に言われたような気がするが 最近は、私もWin32OLEを自分で使っています。 ヘビーユーザーじゃなくてライトユーザーだけど。
| 固定リンク | コメント (0) | トラックバック (0)
21日、22日の2日間、RubyKaigi 2008 に参加。
2日目、頭痛がしたので、午後途中リタイア。 今日もまだ頭痛がするので、とりあえず、感想をちょっとだけ。
サインと写真をお願いされるとは思わなかった。
Rabbit ショッカー軍団の一員としての年1回の義務は果たした(はず)。
意識してゆっくりした英語で喋ってくれたこともあって、英語の講演は去年より理解できたような気がする。 Laurent Sansonettiの英語が私にとっては速かったけど、使っている単語は易しかったので、それなりについていくことができた。
今回、招待していただき、ありがとうございました。 途中リタイアしちゃったし、「動くコンテンツ」としての役割を果たせたかどうかは、疑問ですが、私にとっては有意義な2日間でした。
| 固定リンク | コメント (2) | トラックバック (0)
proprietary なソフトウェアということらしい。
さて、Win32OLEのテストスクリプトはどうやって実現したらいいだろうか。 困った。
| 固定リンク | コメント (0) | トラックバック (0)
まだよくわかっていない。 どのくらいわかっていないかというと、ASRのソースが参考になるのかどうか断定できないくらいにわかっていない。
実現したいことは、python-win32のこの話題と同じこと。
Googleにお伺いしてみたところ、 MFCのOLEのIMessageFilterに関する話題 が見つかった。 どうやら、IMessageFilterを利用するというのは、あながちハズレではなさそう。
以下、まだちゃんと読んでいないのだが、気になったURLのメモ。
IMessageFilterをWin32OLE側で適切に実装して、CoRegisterMessageFilterをコールすれば、python-win32と同じことが実現できる。 ...という考え方で正しいんだろうか。 正しいとすれば、ASRのソースが参考になりそうな気がしてきている。 (というよりも、これらの情報を収集するきっかけとなったASRのCRubyWrapperFilter::Initialize()の実装だけでも十分参考になったと言えます。)
ところで、テストスクリプトを書くにはどうすればいいんだろうか...。
| 固定リンク | コメント (7) | トラックバック (0)
[ruby-talk:298615]の話。
どうやら、MFCの AfxOleGetMessageFilter()経由で EnableBusyDialog とか、EnableNotRespondingDialog とか、SetMessagePendingDelayとか をコールすればいいということらしい。
まず、RubyのWin32OLEは、Cで書いてあって、MFCを使うつもりは全くない。 なので、APIを呼ぶことにしたいんだけど、どうすればいいのか、よくわからない。 MFCのソースも手元にないし。 SetMessagePendingDelayは、IMessageFilter インターフェースを使えば、 もしかしたら、なんとかなるのかも知れないなと思っているんだが、よくわからない。 あとの2つは、さっぱりわからない。
誰かヒントでもいいから教えてください。 なんならパッチを送ってくれてもいいです。 (むしろ、その方が嬉しいです。)
| 固定リンク | コメント (2) | トラックバック (0)
英語の勉強を兼ねて買った。 読み始めたけど、Rubyそのものは知っているので、今のところは英語は難しく感じられない。 が、
"%d %s" % [3, "rubies"]
という書き方を今まで知らなかった。
| 固定リンク | コメント (0) | トラックバック (0)
もはや、1.8の機能なんだか1.9の機能なんだか自分の中で区別がつかなくなってきている。
| 固定リンク | コメント (0) | トラックバック (0)
うーん。どうするのがいいんだろうか。
| 固定リンク | コメント (0) | トラックバック (0)
Part I の Ruby.new の Some Basic Ruby まで読んだ。
文字列の中で良く
"This is #{var}"
みたいな書き方をするけど、インスタンス変数、クラス変数、グローバル変数の場合
"This is #@var"
"This is #@@var"
"This is #$var"
みたいに{}を省略できることを知らなかった。 自分では無条件に{}をつけていた。
この場合は{}を省略できるとか一々考えるのが面倒くさいから、今後も無条件に{}をつけそうな気がする。
| 固定リンク | コメント (0) | トラックバック (0)
1.8だと、WIN32OLE#setproertyを使えばいいのだ。
dict["ruby"] = "RUBY"
は、1.8では
dict.setproperty("item", "ruby", "RUBY")
となる。
| 固定リンク | コメント (0) | トラックバック (0)
えーと。 次のスクリプトを1.8でも1.9と同じように動くようにするにはどう書いたらいいんだっけ?
require 'win32ole'
dict = WIN32OLE.new('Scripting.Dictionary')
dict.add("ruby", "Ruby")
begin
puts dict["ruby"] # 1.9 の新機能
dict["ruby"] = "RUBY" # 1.9の新機能
puts dict["ruby"]
rescue
puts "does not work in Ruby #{RUBY_VERSION}" # 1.8 以前
end
1.8 だと
puts dict["ruby"]
は、
puts dict.Item("ruby")
でいいんだけど、
dict["ruby"] = "RUBY"
は、どう書けばいいんだっけ?
| 固定リンク | コメント (0) | トラックバック (0)
Ruby 1.9.0 は、1.8系に比べて速くなっていると言われている。 話には、聞いているのだけど、実感したことが無かったので、実際に試してみた。 今回、nonoを使って試してみた。 nonoにののぐらむを解かせてみて、Ruby 1.8 系と Ruby 1.9とではどのくらい差が出るのか試すことにした。 使ったバージョンは以下の通り。
nono 0.1.7 ruby 1.8.6 (2007-12-27 patchlevel 5000) [i686-linux] ruby 1.9.0 (2007-12-30 revision 0) [i686-linux]
解かせるののぐらむは、 ののぐらむ解法教室 の実践編の上級者コースの問題にした。
それぞれ、nono.rb を使って3回ずつ解かせて平均を取ってみた。 Ruby 1.8.6 では、平均 183.9 秒、Ruby 1.9.0 では、平均 49.7 秒という結果で、Ruby 1.9.0の勝利となった。 微妙に速い結果しか出なかったらどうしようかと思っていたのだが、 これだけ差が出れば、はっきりと1.9の方が速いと断言できる。 ほっとした。
これで、「1.9.0って速くなってるの?」と他人から聞かれたときに、 「なんか速くなってるみたいだよ。」という適当な言葉でお茶を濁さず、 「自分が作ったプログラムで試したことがあるんだけど、Ruby 1.8.6 だと 180秒ぐらいかかった処理が、 1.9.0 だと 50秒ぐらいで終わったよ。それぐらい速くなってるよ。」 とそれなりに説得力のある返事をすることができるようになった。
| 固定リンク | コメント (0) | トラックバック (0)
Ruby 1.9.0 で VisualuRuby が動作するか試してみた。
RSTRING(XXX)->len
RSTRING(XXX)->ptr
がことごとくエラーになったので、間違っているかも知れないけど、 適当にRSTRING_LEN と StringValuePtrで全部置き変えた。(12/30追記:StringValuePtrじゃなくて本来は、RSTRING_PTRを使うべきかも知れない。)
スクリプト側は、インストーラが動かない。
attr :XXX,1
の1がことごとくエラーになるからだが、どうすればいいのかソースを追いかけて考えるのが面倒だったので、
attr :XXX
にことごとく変えてみたが、やっぱり駄目だった。
ということで、Simple OLE BrowserのRuby 1.9.0対応版は、 しばらく、おあずけ。
あれ、ひょっとして
attr :XXX, 1
は
attr_accessor :XXX
にすればいいのか?
ちょっと時間が無いので、また今度。
| 固定リンク | コメント (2) | トラックバック (0)
ふと、間違ってうまく動いちゃったりすることもあったりしちゃうんじゃないかと思って試してみた。
irb(main):001:0> RUBY_VERSION
=> "1.9.0"
irb(main):002:0> RUBY_RELEASE_DATE
=> "2007-12-21"
irb(main):003:0> require 'win32ole'
=> true
irb(main):004:0> def ByVal(x)
irb(main):005:1> WIN32OLE_VARIANT.new(x)
irb(main):006:1> end
=> nil
irb(main):007:0> p(ByVal 1)
#<WIN32OLE_VARIANT:0x7ff05e04>
=> #<WIN32OLE_VARIANT:0x7ff05e04>
irb(main):008:0> p(ByVal 1, ByVal 2)
SyntaxError: (irb):8: syntax error, unexpected tINTEGER, expecting keyword_do or '{' or '('
p(ByVal 1, ByVal 2)
うんうん。そりゃそうだよねえ。やっぱり、VBっぽい値渡しは無理だよねえ。うんうん。
| 固定リンク | コメント (0) | トラックバック (0)
なんか久し振りにRuby1.9(ruby-trunk)をLinuxでコンパイルしたらエラーが出たので、ruby-devで質問したruby-dev:32419。 なかださんからbisonをバージョンアップしろとの回答があった。 ということで、Vine Linuxのbisonは2.1なので仕方なくソースからbisonをコンパイルすることにした。 ついでに(何のついでだかわからないが)物は試しということで、GCCもバージョンアップしてみることにした。
最初に、binutils。
tar jxvf binutils-2.18.tar.bz2 cd binutils-2.18 CFLAGS=-Os ./configure make make install cd ..
次にGCC。
tar jxvf gcc-core-4.2.2.tar.bz2 tar jxvf gcc-g++-4.2.2.tar.bz2 cd gcc-4.2.2 CFLAGS=-Os CXXFLAGS=-Os CC=/usr/bin/gcc ./configure --enable-languages=c++ \ --with-system-zlib --enable-sjlj-exceptions --enable-threads \ --disable-version-specific-runtime-libs --disable-nls make CFLAGS=-Os LIBCFLAGS=-Os LIBCXXFLAGS=-Os \ STAGE1_CFLAGS=-Os BOOT_CFLAGS=-Os bootstrap make install cd ..
bisonをバージョンアップする前に何かの間違いで、ruby-trunkをGCC4.2.2でコンパイルできちゃうんじゃないかと 思ってやってみたけど、やっぱり駄目だったので、素直に、bisonをバージョンアップした。
tar jxvf bison-2.3.tar.bz2 cd bison-2.3 ./configure --disable-nls make make install
ということで、再度、ruby-trunkをコンパイルしてみたら、今度はちゃんとできた。
ということで、本日の結論。 Ruby 1.8 は今のところ大丈夫だけど、Ruby 1.9をコンパイルするときには、bison 2.1では駄目。 bison 2.3にバージョンアップしよう。 念のために断わっておくと、GCCをバージョンアップしたのは私の単なる気紛れ。 GCCのバージョンアップは必要ないはず。
| 固定リンク | コメント (0) | トラックバック (0)
今週ずっと体調が悪かったのだが、少し元気が出てきたので、前々から調べていたものを整理してみた。
英語100万語を実践すべくミステリを中心に段階的に読み進んできた。 現在は、英語177万語、SSSで言うところのレベル6あたりに位置している。 そろそろ、技術書の類にも手を出すのもいいかも知れないと思い始めた。 とは言っても、いきなり知らない分野の本に手を出しても途中で挫折する可能性が高い。 もっとも、SSSでは「面白くなかったらやめる」という原則があるので、途中で投げ出すこと自体は悪いことではない。 ただ、私としては、最後まで読んで達成感も味わいたい。 そこで、Ruby関係の本なら何とかなるかと思い、ちょっとAmazonで調べてみた。 全部、英語だと思うけど、違う言語の本が紛れ込んでいるかも知れない。 なお、今回は敢えてAmazon.comの方にリンクした。 Amazon.co.jpだと書籍の内容の紹介が無いものが多いためである。 また、順番は多少意図的だけど、それほど深い意味はないということを強調しておく。
Ruby 言語系だと以下の通り。 最後の2冊は、Ruby on Rails寄りかも知れない。
Ruby on Rails系だと以下の通り。 Ruby for RailsというRailsユーザーのためのRuby解説本というのもある。 Foundations of RSpecは、Rails寄りなのかどうかはっきりしない。 最後の2冊は、純粋なRuby on Railsの本からはちょっとずれているかも知れない。
RubyまたはRailsに関連していると思われるJava関係の本。 Ravenは、ちょっと他とは種類が違うかも知れない。
どこに分類すべきか迷った本
From Java to Ruby (日本語訳あり)
あと、番外編として、
をピックアップしておく。
Kent 自らが Customer Discussions で、
I think the book will be helpful for Ruby programmers, although you will need to translate some of the specific advice to apply to Ruby.
と回答しているので、Rubyユーザーにも役立つ本みたいである。 (話は、ずれるけど、Amazon.comのCustomer Discussionってちょっと面白い。)
私の英語の能力はしょぼいので、Kent BeckのXP本(1st Edition)をちょこっと読んだとき、 英語が難しく感じられたんだけど、Implementation Patternsはどうだろうか。
他にも、(2006年以降に出版された)プログラミング言語Rubyに関係する英語の本がありましたら、教えてください。 あと、この中でオススメだよというのがありましたら、教えてください。
| 固定リンク | コメント (0) | トラックバック (0)
まだ、私は、Ruby m17nを全くわかっていない。 どのくらいわかっていないかというと、 WIN32OLE.codepage=周りをRuby m17nに合わせてなんか配慮した方が いいかどうかが全く判断できないぐらいわかっていない。
以前、Win31OLEでも -K オプションに合わせてcodepageを 変更してくれという要望があったんだけど、-Kオプションが残るのか どうかわからないので、保留にしていた。 そろそろ、考えなきゃいけないような気がしているのだが、 結局、-Kオプションはどうなるか決まったのかどうかも良くわからない。
ちなみに、今のWin32OLEは、-Kオプションのことは完全無視。 WIN32OLE.codepage= で独自にcodepageを設定できるようになっている。 デフォルトは、CP_ACP。
| 固定リンク | コメント (0) | トラックバック (0)
Lightweight Language AHPをやってみた。
SUKE さんにオススメの LL は Ruby (44%) > PHP (22%) > Perl (17%) > Python (17%) です!
となった。 PerlとPythonが同点に見えるけど、正確には、Perlが16.75%で、Pythonが16.60%だった。 PHPは全く知らないので、誤解十分のイメージで答えたらこうなった。 最近の私は、JavaScriptだったり、VB.NETだったり、C#だったりするんだけど。
| 固定リンク | コメント (0) | トラックバック (0)
やればできるもんだ(ruby-talk:271710)。 AddFromString使った方がもっと素直に書けたな。 彼がやりたい事は、本当にこういう事なのか? ちょっと読み違えているかも。
| 固定リンク | コメント (0) | トラックバック (0)
Comboboxを作って、そのイベントを拾うWin32OLEのサンプル(ruby-talk:271658)。 意外とWin32OLEで頑張れるもんだなあ。 風邪が治りかけなんだから早く寝ようと思ってたのに、 ついムキになって調べてしまった。
| 固定リンク | コメント (0) | トラックバック (0)
イベントを通知してもらうWIN32OLEオブジェクトの寿命と同じにするのが 使う人にとってわかりやすい実装のような気がしてきた。 変更するとどのくらいの人がギャッと言うだろうか?
イベントを扱うために、 WIN32OLE_EVENTクラスを導入したこと自体が 失敗だったかも知れないと思う今日この頃。
| 固定リンク | コメント (0) | トラックバック (0)
うーん。どうもWIN32OLE_EVENT#unadviseが問題という訳でも無いような...。
| 固定リンク | コメント (0) | トラックバック (0)
なんとなくRUBY_CRITICALなら十分な気がする。EnterCriticalSectionだと十分なのかどうかわからない。
| 固定リンク | コメント (0) | トラックバック (0)
とりあえず、unadviseを使うとGCされることを確認した。確認に使ったのは、gctest.rb。
test_win32ole_event.rbへのテストの追加は確実にGCされるタイミングがわからないから保留。
| 固定リンク | コメント (0) | トラックバック (0)
WIN32OLE_EVENTオブジェクトを途中でGCできないのは、 次のようなスクリプトを考慮しているから
ie = WIN32OLE.new('InternetExplorer.Application')
ev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents')
ev.on_event{|*args| handler(*args)}
# ここでGC発生
ie.visible = true
ie.navigate(url) # handlerに通知したい
# ここで二度目のGC発生
while true
WIN32OLE_EVENT.message_loop
sleep 0.1
end
ev.on_event でイベントハンドラを定義しても、 その直後にGCが発生してevがGCされてしまうと イベントを拾うことができない。
そこで、WIN32OLEオブジェクトがGCされない間、 つまり ieがGCされない間、evがGCされなければいいじゃん という意見を頂戴した。 一瞬、いい案に思えたんだけど、上の例の二度目の GCの後でも、ieはGCされても、InternetExplorerのプロセスは残るし マウスで、Internet Explorerを操作できる。 その間にevがGCされると、イベントを拾うことができなくなる。 (現状では、evはGCされないので、イベントを拾い続ける。)
結局のところ、単純に ev がGCされるてもいいときは、 通知を受ける必要がなくなったときで、 それは、スクリプトを書いている人が判断すりゃいいじゃん という投げやりな結論になってしまった。
ということで、もう通知は必要ないよというためのメソッド WIN32OLE_EVENT#unadviseを trunkに追加してみた。
本当にGCされるかどうかは、まだ検証していないのだけど、 unadviseするとそれ以降は、通知されなくなるのは確認済み。
こういうのを用意すると、逆のWIN32OLE_EVENT#adviseも 欲しくなるんじゃないかと思うのだけど、 そっちは手元でテスト中なのでコミットはまだ。
名前は、IConnectionPoint の Unadviseから取ったんだけど、 ピンとこない人の方が多いかな。
| 固定リンク | コメント (8) | トラックバック (0)
Scripting ActiveX control in WSHに 書かれていることがWin32OLEにも当てはまる。 で、これがバグか否かということなんだけど、私としては、 バグではないという立場を取っている。
元々、Win32OLEは、IDispatchインターフェースを通じて COMサーバーにいろいろやらせることができる 拡張ライブラリであるというのが出発点。 基本的にIDispatch以外のインターフェースのことは考えていない。 ましてや、IPersistXXX->InitNewを事前に呼び出さなくてはならないということなんて 考えたことも無かった。
他のインターフェースのことまで考慮してごにょごにょするのは Win32OLEの守備範囲外だと思っている。 MFC ActiveX コントロールを使えないのはバグではなくて、 Win32OLEの限界(仕様)というのが私の考えだ。 そもそもWSHだってサポートしてないみたいだし。
なので、バグフィックスを主眼にしたRuby 1.8.6系(ruby_1_8_6 branch)に MFC ActiveXコントロールのサポートを追加するつもりはない。
でも、Ruby 1.8系(ruby_1_8 branch)は、1.9系を見据えたbranchという 位置づけでもあるので、MFC ActiveXコントロールをもしかしたら サポートしているかも知れない機能を追加してみた。
なので、1.8.6では駄目だけど、1.8.7以降では、もしかしたらMFC ActiveX コントロールの一部がWin32OLEから利用できるかも知れない。
ちなみに、Visual Studio で、MFC ActiveXコントロールをウィザードで設定を一つも 変更せず、ソースも1行も変更せずに作ったActiveXコントロールを使って
require 'win32ole'
obj = WIN32OLE.new('MFC ActiveXコントロールのProgID')
obj.ole_activex_initialize
obj.aboutbox
と実行して確認しただけである。
機能追加に合わせてテストスクリプトも追加したかったんだけど、 標準のWindowsにあるIPersistMemory->InitNewを呼ばないと使えないActiveX コントロールがわからなかったので、テストは断念した。
| 固定リンク | コメント (3) | トラックバック (0)
Ruby 1.8系でもWIN32OLE_TYPE#progidのバグは対応しようと思って ちょっと作業中である。
それとは別件で、MFCで作られたActiveXコントロールへの対応機能を 1.8.6にも追加してくれないかという要望が来ている。
この機能だけは、既存のソースを書き変える必要がない(下位互換性は保証される)ので、 ruby_1_8 になら追加してもいいかもと考え始めている。
ruby_1_8系列には、 「1.9との前方互換性向上(機能先取りの積極的なbackport)」 という面もあることだし([ruby-dev:30560])。
それから、MFCで作られたActiveXコントロールへの対応はバグフィックスではなく、 あくまでも、新機能の追加という位置づけであることを強調しておきたい。
と、ここに日本語で書いても伝わらないのだろうな。きっと。