[ruby-dev:31743] deprecating RUBY_VERSION_CODE

From: Nobuyoshi Nakada <nobu@...>
Date: 2007-09-06 04:50:59 UTC
List: ruby-dev #31743
なかだです。

[ruby-core:12068]で思い出したのですが、めんどくさいのでdevに振り
ます。

At Tue, 3 Apr 2007 15:30:16 +0900,
Yukihiro Matsumoto wrote in [ruby-core:10847]:
> |Furthermore, I'd rather want to remove RUBY_VERSION_CODE from
> |version.h, and change RUBY_VERSION object to a particular
> |object from mere String.
> 
> It is arguable.

RUBY_VERSIONをRuby::VersionNumberというクラスのオブジェクトにし
てみました。最初はto_strを持つだけのStructにしようかと思ったんで
すが、gsubなどが使われていたので中身はそのままStringにしてしまい
ました。


Index: version.c
===================================================================
--- version.c	(revision 13347)
+++ version.c	(working copy)
@@ -20,15 +20,90 @@ const char ruby_platform[] = RUBY_PLATFO
 const int ruby_patchlevel = RUBY_PATCHLEVEL;
 
+static VALUE
+version_init(VALUE self, VALUE major, VALUE minor, VALUE teeny)
+{
+    char buf[(sizeof(long)*CHAR_BIT/3+(sizeof(long)*CHAR_BIT<80))*3];
+
+    rb_call_super(0, 0);
+    snprintf(buf, sizeof buf, "%u.%u.%u", NUM2UINT(major), NUM2UINT(minor), NUM2UINT(teeny));
+    rb_str_cat2(self, buf);
+    rb_iv_set(self, "major", major);
+    rb_iv_set(self, "minor", minor);
+    rb_iv_set(self, "teeny", teeny);
+    OBJ_FREEZE(self);
+    return self;
+}
+
+#define version_attr(n) \
+static VALUE version_##n(VALUE self) {return rb_attr_get(self, rb_intern(#n));}
+
+version_attr(major)
+version_attr(minor)
+version_attr(teeny)
+
+static VALUE
+version_to_a(VALUE self)
+{
+    return rb_ary_new3(3, version_major(self), version_minor(self), version_teeny(self));
+}
+
+static VALUE
+version_cmp(VALUE self, VALUE other)
+{
+    VALUE tmp = rb_check_convert_type(other, T_ARRAY, "Array", "to_a");
+    long i;
+
+    if (NIL_P(tmp)) {
+	VALUE sep = rb_const_get(rb_obj_class(self), rb_intern("Separator"));
+	tmp = rb_ary_to_ary(rb_funcall2(other, rb_intern("split"), 1, &sep));
+    }
+    other = rb_ary_new2(RARRAY_LEN(tmp));
+    for (i = 0; i < RARRAY_LEN(tmp); ++i) {
+	VALUE e = rb_Integer(rb_ary_entry(tmp, i));
+	rb_ary_push(other, e);
+    }
+
+    self = rb_convert_type(self, T_ARRAY, "Array", "to_a");
+    return rb_ary_cmp(self, other);
+}
+
+static VALUE
+ruby_version_number(VALUE mRuby)
+{
+    VALUE cVer = rb_define_class_under(mRuby, "VersionNumber", rb_cString);
+
+    rb_define_method(cVer, "initialize", version_init, 3);
+    rb_define_method(cVer, "to_ary", version_to_a, 0);
+    rb_define_method(cVer, "to_a", version_to_a, 0);
+    rb_define_method(cVer, "<=>", version_cmp, 1);
+    rb_define_method(cVer, "major", version_major, 0);
+    rb_define_method(cVer, "minor", version_minor, 0);
+    rb_define_method(cVer, "teeny", version_teeny, 0);
+    rb_define_const(cVer, "Separator", rb_reg_new(rb_str_new("\\.", 2), 0));
+
+    return rb_funcall(cVer, rb_intern("new"), 3,
+		      INT2FIX(RUBY_VERSION_MAJOR),
+		      INT2FIX(RUBY_VERSION_MINOR),
+		      INT2FIX(RUBY_VERSION_TEENY));
+}
+
 void
 Init_version(void)
 {
-    VALUE v = rb_obj_freeze(rb_str_new2(ruby_version));
+#define RUBY_CONST(name, val) do {			\
+	static const char varname[] = name;		\
+	rb_define_const(mRuby, varname + 5, val);	\
+	rb_define_global_const(varname, val);		\
+    } while (0)
+    
+    VALUE mRuby = rb_define_module("Ruby");
+    VALUE v = ruby_version_number(mRuby);
     VALUE d = rb_obj_freeze(rb_str_new2(ruby_release_date));
     VALUE p = rb_obj_freeze(rb_str_new2(ruby_platform));
 
-    rb_define_global_const("RUBY_VERSION", v);
-    rb_define_global_const("RUBY_RELEASE_DATE", d);
-    rb_define_global_const("RUBY_PLATFORM", p);
-    rb_define_global_const("RUBY_PATCHLEVEL", INT2FIX(RUBY_PATCHLEVEL));
+    RUBY_CONST("RUBY_VERSION", v);
+    RUBY_CONST("RUBY_RELEASE_DATE", d);
+    RUBY_CONST("RUBY_PLATFORM", p);
+    RUBY_CONST("RUBY_PATCHLEVEL", INT2FIX(RUBY_PATCHLEVEL));
 }
 


-- 
Nobu Nakada

In This Thread

Prev Next