# Ruby Compressor (little long)

**URL:** <https://www.ruby-forum.com/t/ruby-compressor-little-long/65268>\
**Category:** Ruby\
**Created:** [August 17, 2006, 3:37am UTC](https://www.ruby-forum.com/t/ruby-compressor-little-long/65268 "2006-08-17T03:37:25Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![patrickharlan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/77aa72/32.png) [@patrickharlan](https://www.ruby-forum.com/u/patrickharlan)\
**Post date:** [August 17, 2006, 3:37am UTC](https://www.ruby-forum.com/t/ruby-compressor-little-long/65268/1 "2006-08-17T03:37:25Z")

</div>

I have need to distribute applications to customers. The customers  
have every right to the source code, but when it is installed we do  
not want the code to be easily visible. We are not worried about super  
hackers (or even moderately strong Ruby programmers :-), we just do  
not want our raw source code on the system calling out to be played  
with by the end users.

To this end, I have developed this very simple script, which I plan on  
further refining. I know there are many rough edges, but I wanted to  
see if anyone else was interested in the code (or had any other  
suggestions), before I went any further.

require “zlib”

@init = \<\<ZLIB\_REQUIRE  
module Kernel  
alias default\_require require  
@@zlib\_requires = {}

def zlib\_requires=(zr)  
@@zlib\_requires = zr  
end

def require(path)  
return false if $".include?(path)

```
if @@zlib_requires.has_key(path)
  eval(Zlib::Inflate.inflate(@@zlib_requires[path]))
  $" << path
else
  default_require path
end

```

end

end  
ZLIB\_REQUIRE

@bootstrap = \<\<BOOTSTRAP  
require “zlib”  
File.open( **FILE** , “rb”) do |data|

# skip to the end

line = data.gets until line =~ /^ **END** $/  
f = Marshal.load(data)  
eval(Zlib::Inflate.inflate(f[:init]))  
Kernel.zlib\_requires = f  
eval(Zlib::Inflate.inflate(f[:main]))  
end  
**END**  
BOOTSTRAP

def findrb(fname)  
$:.each do |path|  
fp = File.join(path, fname)  
return fp if File.exists? fp  
end  
false  
end

def compress(script)  
files = {}  
load(script) rescue nil

$".each do |fname|  
if (File.extname(fname) == “.rb”) && (fp = findrb(fname))  
data = IO.read(fp)  
files[fname] = Zlib::Deflate.deflate(data, Zlib::BEST\_COMPRESSION)  
end  
end

files[:main] = Zlib::Deflate.deflate(IO.read(script),  
Zlib::BEST\_COMPRESSION)  
files[:init] = Zlib::Deflate.deflate(@init, Zlib::BEST\_COMPRESSION)

File.open(“compress-#{script}”, “wb”) do |io|  
io.print @bootstrap  
io.write(Marshal.dump(files))  
end

# write header data - fname,

end

compress(ARGV[0])

---

<div class="post-metadata">

**Author:** ![patrickharlan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/77aa72/32.png) [@patrickharlan](https://www.ruby-forum.com/u/patrickharlan)\
**Post date:** [August 17, 2006, 4:16am UTC](https://www.ruby-forum.com/t/ruby-compressor-little-long/65268/2 "2006-08-17T04:16:28Z")

</div>

I havent personally used this to distribute an application, but it  
sounds like it’ll fit the bill:

[http://www.erikveen.dds.nl/allinoneruby/index.html](http://www.erikveen.dds.nl/allinoneruby/index.html)

---

<div class="post-metadata">

**Author:** ![patrickharlan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/77aa72/32.png) [@patrickharlan](https://www.ruby-forum.com/u/patrickharlan)\
**Post date:** [August 17, 2006, 4:46am UTC](https://www.ruby-forum.com/t/ruby-compressor-little-long/65268/3 "2006-08-17T04:46:31Z")

</div>

On 8/16/06, Scott [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > hackers (or even moderately strong Ruby programmers :-), we just do  
> > @init = \<\<ZLIB\_REQUIRE
> > 
> > **END**  
> > def compress(script)  
> > files[:main] = Zlib::Deflate.deflate(IO.read(script), Zlib::BEST\_COMPRESSION)  
> > compress(ARGV[0])

I have used this and rubyscript2exe they are wonderful, but serve a  
slightly different purpose. I just want to hide the code a little bit.  
In our particular case installing Ruby is not a real problem.

Thanks  
pth

---

<div class="post-metadata">

**Author:** ![patrickharlan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/77aa72/32.png) [@patrickharlan](https://www.ruby-forum.com/u/patrickharlan)\
**Post date:** [August 17, 2006, 9:22am UTC](https://www.ruby-forum.com/t/ruby-compressor-little-long/65268/4 "2006-08-17T09:22:47Z")

</div>

This:  
File.open( **FILE** , “rb”) do |data|

# skip to the end

line = data.gets until line =~ /^ **END** $/  
f = Marshal.load(data)  
eval(Zlib::Inflate.inflate(f[:init]))  
Kernel.zlib\_requires = f  
eval(Zlib::Inflate.inflate(f[:main]))  
end  
**END**

Can be changed to:  
f = Marshal.load(DATA.read)  
eval(Zlib::Inflate.inflate(f[:init]))  
Kernel.zlib\_requires = f  
eval(Zlib::Inflate.inflate(f[:main]))  
end  
**END**

---

<div class="post-metadata">

**Author:** ![patrickharlan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/77aa72/32.png) [@patrickharlan](https://www.ruby-forum.com/u/patrickharlan)\
**Post date:** [August 17, 2006, 2:05pm UTC](https://www.ruby-forum.com/t/ruby-compressor-little-long/65268/5 "2006-08-17T14:05:08Z")

</div>

On 8/17/06, Joey [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Can be changed to:  
> f = Marshal.load(DATA.read)  
> eval(Zlib::Inflate.inflate(f[:init]))  
> Kernel.zlib\_requires = f  
> eval(Zlib::Inflate.inflate(f[:main]))  
> end  
> **END**

Thanks, I had tried that – plus a DATA.binmode (without which it did  
not work on Windows at all), but I still had a few issues, it failed  
in odd ways – I did not spend a lot of time tracking it down as I  
knew that reopening the file would work – I will check it again and  
see if I can make it work or give more information on the failure.

pth
