views:

51

answers:

2

I have a mod_rails server where disk space, oddly enough, is at a premium. Is there a way for me to compress my application's source, like Python's zipimport?

There are obvious disadvantages to this, so I should probably just break down and spend a nickel on disk space, but I figured it'd be worth a shot.

+1  A: 

require and load are just methods like any other. You can undefine them, redefine them, override them, hook them, wrap them to do anything you want. In fact, that's exactly how RubyGems works.

Now, I don't know whether someone has already implemented this for you, but I actually remember some discussions about this on the ruby-talk mailinglist.

However, there are some examples of loading library code from alternative locations that you can look at, and maybe copy / adapt what they are doing for your purpose:

  • http_require does pretty much what it sounds like: it allows you to require an HTTP URI
  • Crate is a Ruby packaging tool which packages a Ruby application into a single binary and a couple of SQLite databases; it modifies require to load libraries out of an (encrypted) SQLite database instead of the filesystem
  • and of course I already mentioned RubyGems
Jörg W Mittag
+1  A: 

Oh, this is neat. Check out the rubyzip gem:

rubyzip also features the zip/ziprequire.rb module which allows ruby to load ruby modules from zip archives.

Like so. This is just slightly modified from their example:

require 'rubygems'
require 'zip/zipfilesystem'
require 'zip/ziprequire'

Zip::ZipFile.open("/tmp/mylib.zip", true) do |zip|
  zip.file.open('mylib/somefile.rb', 'w') do |file|
    file.puts "def foo"
    file.puts "  puts 'foo was here'"
    file.puts "end"
  end
end

$:.unshift '/tmp/mylib.zip'
require 'mylib/somefile'

foo    # => foo was here

You don't have to use the rubyzip library to create the zipped library, of course. You can use CLI zip for that.

Wayne Conrad