From: Paul Brannan Date: 2005-04-28T01:46:40+09:00 Subject: Re: Precompiling Ruby programs With nodewrap, you can store the code as an AST: [pbrannan@zaphod tmp]$ cat test.rb def foo p 1 + 1 end foo() [pbrannan@zaphod tmp]$ ruby -rnwobfusc test.rb > test2.rb [pbrannan@zaphod tmp]$ cat test2.rb require 'nodewrap' if RUBY_VERSION != "1.8.2" then $stderr.puts "Wrong Ruby version; please use 1.8.2" exit 1 end begin_nodes = Marshal.load("\004\010[\000") n = Marshal.load("\004\010u:\020Node::BLOCK\002c\002\004\010[\ai\004*\255\r {\026i\004z\255\r [\ni\003? \010\"\ftest.rb[\aTi\004\336\255\r [\aTi\004p\255\r 0i\004>\255\r [\ni\003?0!\"\ftest.rb[\aFF:\010foo0i\004\254\255\r [\ni\003?(\021\"\ftest.rb[\aTi\004\312\255\r [\aTi\004\266\255\r :\006+i\004p\255\r [\ni\003? \030\"\ftest.rb[\aTi\004\216\255\r [\aFF0i\004\336\255\r [\ni\003?\020\n\"\ftest.rbi\000i\372[\aFFi\0044\255\r [\ni\003?\370\"\"\ftest.rbi\t[\aTi\004>\255\r 0i\004\242\255\r [\ni\003?P\021\"\ftest.rbi\006[\aTi\004\254\255\r [\aFFi\004f\255\r [\ni\003?\030\030\"\ftest.rb[\aFF0[\aTi\004z\255\r i\004*\255\r [\ni\003? \010\"\ftest.rb[\aTi\004R\255\r [\aTi\004 \255\r 0i\004\230\255\r [\ni\003?0\021\"\ftest.rb[\aTi\004\242\255\r :\006p0i\004\\\255\r [\ni\003?P\n\"\ftest.rb[\aTi\004f\255\r ;\000i\ai\004\312\255\r [\ni\003?\320\021\"\ftest.rb[\aFi\00600i\004 \255\r [\ni\003? \"\ftest.rb[\aTi\0044\255\r [\aFF0i\004\216\255\r [\ni\003?\370\022\"\ftest.rbi\a[\aTi\004\230\255\r 0i\004R\255\r [\ni\003?\370\n\"\ftest.rbi\006[\aTi\004\\\255\r 0i\004\300\255\r [\ni\003?\320\021\"\ftest.rb[\aFi\00600i\004\266\255\r [\ni\003?P\021\"\ftest.rbi\006[\aTi\004\300\255\r [\aFF") begin_nodes.each do |node| node.eval(self) end n.eval(self) [pbrannan@zaphod tmp]$ ruby test2.rb 2 The process is still somewhat reversible, but afaik no one has written a tool yet to do this. I should also note that the code is still experimental, and you should test your code thoroughly after transforming it this way. Paul