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);