Ruby2.0にはVMがついてるのでなんとかすればコンパイルしてexe化!みたいな事ができそうな気がしたので妄想tipsです。
RubyVM::InstructionSequence.compile_file('rubyソースファイル').to_a
でrubyソースファイルをコンパイルして命令列が取れます。
ただし、命令列はシンボルが並んでる配列なので更にマーシャリングが必要です。
せっかくなのでファイルのフルパスをキーとしたハッシュを作ってマーシャリング
Marshal.dump({
'c:/ruby/lib/hoge.rb' =>
RubyVM::InstructionSequence.compile_file('c:/ruby/lib/hoge.rb').to_a
})
hashed_iseqs = Marsha.load('上の奴')
def require path
RubyVM::InstructionSequence.load(hashed_iseqs['c:/ruby/lib'+path]).eval
end
hashed_iseqs['main'].eval
みたいな事やればコンパイルしたデータ(ファイル1個!)と
stub(適当実装ならruby.exeとbootstrap.rbとbatで)でrubyを持ってない人にでも配布できるんじゃ
っというただの妄想です。
実用化の為の問題点
・サーチパスを真面目に実装する必要がある
・どのデータを配布データに含めるかの調査
・最大の問題
RubyVM::InstructionSequence.loadは現在使えない状態にある
require 'fiddle'
class RubyVM
class InstructionSequence
addr = Fiddle.dlopen(nil)['rb_iseq_load']
fn = Fiddle::Function.new(
addr, [Fiddle::TYPE_VOIDP] * 3, Fiddle::TYPE_VOIDP)
define_singleton_method(:load) do |dat, par=nil, opt=nil|
fn.call(Fiddle.dlwrap(dat), par, opt).to_value
end
end
end
で使えるらしい
バイトコードのローディング
で、これ何の意味があるの?
利点としてはruby.exe本体に全く手を入れなくても配布用パッケージを作れます
完全なexe化の為にはbootstrap部分を勝手に読み込むようにちょちょいっと細工してstub作らないといけませんが