There are a few options, like RubyScript2Exe or AllInOneRuby. However, all obfuscators of interpreted languages tend to have a serious flaw: they usually don't understand more sophisticated metaprogramming techniques.
That is, they can't necessarily tell that something like foo.send(:bar, ...)
is an invocation on the bar
method in a completely different library, or that eval("require %w{abc def ghi}")
means to require three different libraries. These are trivial examples -- things get much more complex when you throw method_missing
and its ilk into the mix.
When an obfuscator encounters this sort of code, it will dutifully compile the appropriate instructions, but it may not know to also include certain libraries or other code from elsewhere. That can cause serious issues, since the dynamically include
d or require
d will not be available at runtime in a statically linked executable.
Unfortunately, many gems and libraries use sophisticated metaprogramming techniques. You'll likely get into trouble here if you try to use obfuscation and expect your program to have the same behavior. Worse still, because there are so many levels of indirection, if a bug occurs in the obfuscated version, you may never know what exactly happened or how to reproduce it.