The following patch allows testing for a minimal Ruby version using the
`require' statement, like

#!/usr/bin/ruby
require "1.6"
require "thread"
...

If and only if the require param matches /^\d+(\.\d+)*$/ it's a version
test. If the test fails a short message is displayed containing the
required Ruby version, and Ruby exits. The test follows all library loading
attempts, so if a `1.6.rb' library is present, that gets loaded and no
testing is done.

pro:
- simple, intuitive syntax. No need for `if RUBY_VERSION' constructs
- has the perl nature ;)

con:
- overloading require might violate the PoLS(tm)

It's my first shot at hacking ruby internals, so if I picked the wrong rb_*
calls feel free to correct them. The patch is against 1.6.1.

regards,
Michel


--- eval.c.orig	Wed Sep 27 05:43:12 2000
+++ eval.c	Wed Oct  4 21:02:46 2000
@@ -16,6 +16,7 @@
 #include "node.h"
 #include "env.h"
 #include "rubysig.h"
+#include "version.h"
 
 #include <stdio.h>
 #include <setjmp.h>
@@ -5107,7 +5108,7 @@
 rb_f_require(obj, fname)
     VALUE obj, fname;
 {
-    char *ext, *file, *feature, *buf; /* OK */
+    char *ext, *file, *feature, *buf, *version; /* OK */
     volatile VALUE load;
     int state;
     volatile int safe = ruby_safe_level;
@@ -5182,6 +5183,24 @@
 	goto load_dyna;
     }
 #endif
+
+    /* check for Ruby version */
+    version = "^\\d+(\\.\\d+)*$";
+    if(rb_reg_match(rb_reg_new(version, strlen(version), 0),
+        rb_str_new2(RSTRING(fname)->ptr)) != Qnil)
+    {
+        if(rb_str_cmp(rb_str_new2(RUBY_VERSION),
+            rb_str_new2(RSTRING(fname)->ptr)) < 0)
+        {
+            fprintf(stderr,
+                "Ruby %s or later is required to run this script.\n",
+                RSTRING(fname)->ptr);
+            rb_exit(1);
+        }
+        else
+            return Qtrue;
+    }
+
     rb_raise(rb_eLoadError, "No such file to load -- %s",
 	     RSTRING(fname)->ptr);