2008-12-30[n年前へ]
■Rubyスクリプトを実行形式にするスクリプト2種
Rubyスクリプトを実行できる形に変換することができる、RubyScript2Exeと Exerb。(単一ファイルからなるスクリプトならExerbでも可能だが)実行しながら必要ファイル情報などを集め実行形式に直接変換するのRubyScript2Exeで、一回実行することでレシピファイルを作成した後に実行形式ファイルを作成するのがExerb。
RubyScript2Exe.rbは、変換したいスクリプト本体と同じディレクトリに置いて、下記でExeができあがる。
ruby rubyscript2exe.rb hoge.rb
2009-01-01[n年前へ]
■「行く年」と「動的言語」と「来る年」と
12月31日から1月1日に日付が変わる頃、脈絡もなく、「人生」は「動的に色々なものが定まっていくプログラム」と似ているのかもしれない、とふと考えました。
そのどちらも、実行前に何かが定まってしまうのではなく、その時その瞬間にさまざまなことが決まっていくように思います。そんな一行一行が積み重なり動いていくさまを、なぜか連想したのです。
Rubyスクリプトを実行できる形に変換することができるRubyScript2Exeというものがあります。このRubyスクリプトは、他の(実行形式に変えたい)Rubyスクリプトを一行一行実行しながら逐次必要ファイル情報などを集めていき、さらにRubyインタプリタも内包させた上で、最終的に実行形式に変換する、というものです。
こういった動作でアプリケーションが作られるということは、実行形式に変換する際のプログラムの動き次第で、最終的に作成される実行形式ファイルが違ったものになる、ということです。たとえば、こんなRubyスクリプトを作ってみます。
i=2008+rand(2) if i>2008 puts 'in case of '+i.to_s sleep 3 require 'win32GuiTest' gui=Win32GuiTest.new # (中略) else puts 'in case of '+i.to_s sleep 3 endRubyScript2Exeは、Rubyスクリプトを実行しながら、必要なものを逐次集めていきますから、実行形式作成時に1行目のiが2009になったとしたら、win32GuiTest.rb ライブラリが読み込まれることになります。しかし、もしも、iに2008なったとしたらwin32GuiTest.rbは読み込まれません。
つまり、実行形式を作成する際に、"i=2008+rand(2)"でiがどうのような値になったかで、win32GuiTest.rb ライブラリの読み込みの有無が異なる2種類の実行形式ファイルができあがるのです。試しに、実行形式作成時のiの値が異なっていたことによる、(RubyScript2Exe.rbで作成した)異なる2種類の実行形式ファイル(2008.exe, 2009.exe)を置いてみました。
さて、実行形式ファイル作成時に、"i=2008+rand(2)"が2008になり、win32GuiTest.rb ライブラリが読み込まれていない実行形式ファイルが2008.exeです。この実行形式ファイル2008.exeを(たとえば実際にあなたが)実行するときには、"i=2008+rand(2)"は2008になるかもしれませんが、2009になることだって1/2の確率であるわけです。
もしも、2008.exeを実行する時にiが2009になったとしたら、必要なライブラリが読み込まれていないので、未定義のクラスや関数が登場することになり例外が発生することになります。
さて、実行形式ファイル作成時に"i=2008+rand(2)"が2009であった2009.exeの場合には、実行時にiが2008になっても2009でも動作します。2009.exeは、"i=2008+rand(2)"が2009になった場合には「ペイント」プログラムを立ち上げて、「初日の出もどき」を描きます。"i=2008+rand(2)"が2008だったら特に何もしません。
「行く年」や「来る年」を見て、その「行く年」「来る年」の中を歩いていくたくさんの人たちをみて、なぜか「動的言語」を連想しました。これが、2009年の一番最初に作ったプログラムです。
2009-06-04[n年前へ]
■rubyscript2exe.rb の Frozen String error
Rubyスクリプトを単独で動作可能なアプリケーションにしてくれるのが RubyScript2Exe(rubyscript2exe.rb)だが(参考記事)、Rubyのバージョンによっては"Frozen String error"を吐いて、動かない場合がある。そんな場合は、 rubyscript2exe.rb and Frozen String errorより、rubyscript2exe.rbの621行目
#$0.replace(File.expand_path("./init.rb"))を
$_0=File.expand_path("./init.rb") alias $__0 $0 alias $0 $_0に変える。これで動くようになる。($0はスクリプトの起動パスを示す"定"数です)
2009-07-26[n年前へ]
■シリアルポートで受信した内容を最前面アプリにキー送信するRubyスクリプト
10年以上前、自分の勉強がてら、シリアル・ポートで受信した内容をエクセルに貼り付けるプログラムをC++で作りました。確か、Windows 98が出た頃で、Windows 2000が出る前だったと思います。
今日、久しぶりに、Windowsでシリアル・ポートで受信した内容をエクセルに貼り付けるプログラムを作り直したくなりました。そこで、Rubyで「シリアル・ポートで受信した内容を最前面アプリにキー送信するスクリプト」を書いてみました。
といっても、スレッドを使いシリアル・ポート送受信を行うRubyのクラス"ComThread"は、少し前に書いています。また、Windowsの(キー操作やマウス操作などを扱う)各種APIを使うためのRubyクラス"Win32GuiTest"も、同じように書いてあります。
ということは、その2つを使うと、こんな風に「シリアル・ポートで受信した内容を最前面アプリにキー送信するRubyスクリプト」を簡単に書くことができます。
require 'comThread' require 'win32GuiTest' class SendKeyComThread < ComThread def receive(data) @gui=Win32GuiTest.new @gui.sendKeys data.strip+"{ENTER}" end end skCom=SendKeyComThread.new(1, Queue.new,nil,0x1807, 9600) skCom.start(:receive=>true) sleep 60 skCom.stopこれだけで?という感じですが、これだけです。このスクリプトを走らせれば、COM1に(9600bpsで)受信した内容を最前面ウィンドーに送信することが(60秒間)できます。
このサンプル・ソースと必要なファイルは、ここに置きました(wincom.rbも必要です)。
計測器等を使う人であれば、この手のスクリプトは結構便利に感じるのではないでしょうか?こうしたスクリプトを書き、自分が使っている計測器や機器の送出コマンドに合わせたデータ加工正規表現を書き、"receive"メソッドをオーバーライドするのがシェフのお勧めメニューになります。もちろん、RubyScript2exeで、アプリケーション化しておけば、さらに便利だと思います。
2009-12-23[n年前へ]
■続 rubyscript2exe.rb のエラー
Rubyスクリプトを実行形式(Windowsで言えば.EXE形式)にするrubyscript2exe.rbというスクリプトがある。このスクリプトは、ただ一つのファイルを(変換したいRubyスクリプトと同じディレクトリに置くだけで使うことができるので)実に便利で重宝する。
しかし、このrubyscript2exe.rbが動作しないことがある。そんなシチュエーションのひとつは以前書いた、rubyscript2exe.rbが"Frozen String error"を出力し動かない場合である。
そして、他にも、
uninitialized constant Gem::RubyGemsVersion (NameError)とか
Couldn't execute this command (rc=256):というメッセージが吐かれ、Rubyスクリプトを実行形式に変換することができないことがある。
そんな時は、DOSプロンプトから、
set RUYBOPT=とか、
set RUBYOPT=-Ke -rkconvとか、適当にRUBYOPTを設定してやると、rubyscript2exe.rbが動くようになる。つまり、
ruby rubyscript2exe.rb hoge.rbという具合で、hoge.rbをhoge.exeに変換することができるようになる。