[Ruby Request For Comments]

Matz noted he wants to take the versioning logic a step further to include
libraries (and I'll even consider versioning classes). This is a draft
proposal for such a versioning scheme.

If we can shake this down to an intuitive, future-proof scheme, I'd be
happy to implement it.

	I welcome your comments,
	Michel

(PS: Matz, congratulations with the grant!)


1. Version check syntax

ruby version
  require "1.6"               # at least 1.6

probably generalised into:
  require "ruby 1.6"          # at least 1.6
  require "ruby == 1.6.1"     # exactly 1.6.1

library version check:
  require "thread"            # any version of thread
          "thread 4.2"        # at least 4.2
          "thread >= 4.2"     # at least 4.2
          "thread == 4.2"     # exactly 4.2
          etc. with <, >, <=, !=

(Maybe even multiple conditions:
  require "thread 4.2; != 4.2.7" # at least 4.2 but not 4.2.7
but that becomes quite ugly real fast...)

The "thread 4.2"-form could also be interpreted as `exactly 4.2' but that
would break a lot of scripts once a library gets updated.


2. How libraries (can) specify their versions

for script libraries (*.rb):
  version "4.2"               # requires a new keyword/builtin
  LIBRARY_VERSION = "4.2"     # this is better, but pollutes namespace

for binary libraries (*.so), every .so implements (e.g.):
  char* library_version(){
    return "4.2";
  }

then retrieve the version string with dlopen/dlsym. This is probably
portable into win*-api's.

2.1 A more fine-grained scheme

> brainstorm = true

Although the former file-level versioning does the job, class-level
versioning might be the future way to go. Something along the lines of

class Aisumasen
  version "4.2"
  ...
end

This of course collides with the current file-level semantics of require.
And, taking this one step further into the realm of versioned interfaces:

class Aisumasen
  version "4.2"

  def apologise
    version "1.1"
    ...
  end

  def apologise
    version "1.0"
    ...
  end
end

But this is probably -- leaving usefulness alone -- too much.

> brainstorm = false


3. Backward compatibility

AFAICS the above scheme does not collide with the current versionless
requires and libraries.

             require "lib"    require "lib 4.2"

lib w/o         current           fall-back*
version        behaviour        (with warning)

lib with        current              new
version        behaviour            check

* to loading the versionless lib

If there are multiple versions of the same library present in the search
path, they are all tried until a match is found. If no library matches the
first on the path is loaded (with a warning?). <uneasy feeling>