matz / zetabits.com (Yukihiro Matsumoto) writes:

> Hmm, both loading from zip archive and versioning are intersting.
> I'd like to see bit more detailed proposal to start up active
> discussion.

OK, just to get the ball rolling.

Let's have a new class, RubyLoader:

  class RubyLoader
    private :initialize

    def require(*args)
      src = find_loadable_file(*args)
      src.load(*args) unless already_loaded(src)
    end

    def find_loadable_file(*args)
      ...
    end

    def already_loaded(src)
      ...
    end

    attr_accessor :search_path
    attr :loaded_files

  end

This internal split of finding, followed by loading, allows us to
override both behaviors. Versioning could be implemented at the 'find'
level. We also make the actual act of loading specific to the thing
found, so that we can support unzipping and network fetching here.

We then implement a collection of loaders, say LoaderChain. This
implements 'require' by calling the require method of each of its
contained loaders in turn. This allows us to implement sets of totally
different load behaviors and still have them appear unified at the user
level.

   LOADER_CHAIN.add_ruby_loader(XML_RPC_LOADER.new(url))

   require 'ruby://lib/net/webdav'

Then we do some clever aliasing to make all this look compatible with
the existing $:, $", and require.

In terms of versioning, I'd like to see some conventions appear.

Every library file could implement some standard local
variables. These won't pollute the user's name space, as they
disappear during a load.

  version = '1.2.3a'
  author  = 'dave / thomases.com'
  needs   = [ 'xmlparser >=1.2', 'soap ==2.0', 'errmsg <3.14']

  module DemoModule

     # ...
  end

(OK, so the actual syntax is ugly: remember you're supposed to
disagree with this :)

Then we could have a versioning version of RubyLoader that checked the
version of the loaded module

   require 'demomodule >= 1.2'

or
   require 'demomodule' { |version, author|
                                version >= '1.2' and author !~ /dave/
                        }

This would require an interpreter change to have 'load' return a
binding object giving us access to the source-file local variables.


Dave