1

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.

keturn
  • 4,780
  • 3
  • 29
  • 40

2 Answers2

2

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

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

(Update: The ziprequire.rb is no longer present in the rubyzip gem, but the source link appears to contain its old content nonetheless.)

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.

Per Lundberg
  • 3,837
  • 1
  • 36
  • 46
Wayne Conrad
  • 103,207
  • 26
  • 155
  • 191
  • 1
    Interesting indeed. It looks (from a quick glance) that ziprequire.rb is not there any more. Apparently, [there is an issue](https://github.com/rubyzip/rubyzip/issues/51) about it. [Here](https://github.com/rubyzip/rubyzip/commit/794c9463fcb2f5a0bd41f4645978e691c66b0ea6) is the actual commit in which is was removed from the "official" RubyZip repo. Of course, it can still be added in your own project(s) as needed... – Per Lundberg Oct 10 '13 at 21:05
  • Edited post to this avail. – Per Lundberg Oct 10 '13 at 21:06
1

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
  • 363,080
  • 75
  • 446
  • 653