|
|
diff --git a/shotgun/lib/subtend/ruby.c b/shotgun/lib/subtend/ruby.c
index b96828e..68b7c8d 100644
--- a/shotgun/lib/subtend/ruby.c
+++ b/shotgun/lib/subtend/ruby.c
@@ -82,65 +82,63 @@ VALUE subtend_get_global(int which) {
CTX;
switch(which) {
- case 0:
+ case T_OBJECT:
val = ctx->state->global->object;
break;
- case 1:
+ case T_ARRAY:
val = ctx->state->global->array;
break;
- case 2:
+ case T_BIGNUM:
val = ctx->state->global->bignum;
break;
- case 3:
+ case T_CLASS:
val = ctx->state->global->class;
break;
- case 4:
+ case T_DATA:
val = ctx->state->global->data;
break;
- case 5:
+ case T_FALSE:
val = ctx->state->global->false_class;
break;
- case 6:
+ case T_INTEGER:
+ case T_FIXNUM:
val = ctx->state->global->fixnum_class;
break;
- case 7:
+ case T_FLOAT:
val = ctx->state->global->floatpoint;
break;
- case 8:
+ case T_HASH:
val = ctx->state->global->hash;
break;
- case 9:
+ case T_IO:
val = ctx->state->global->io;
break;
- case 10:
+ case T_MODULE:
val = ctx->state->global->module;
break;
- case 11:
+ case T_NIL:
val = ctx->state->global->nil_class;
break;
- case 12:
+ case T_REGEXP:
val = ctx->state->global->regexp;
break;
- case 13:
+ case T_STRING:
val = ctx->state->global->string;
break;
- case 14:
+ case T_SYMBOL:
val = ctx->state->global->symbol;
break;
- case 15:
+ case T_THREAD:
val = ctx->state->global->thread;
break;
- case 16:
+ case T_TRUE:
val = ctx->state->global->true_class;
break;
- case 17:
- val = ctx->state->global->fixnum_class;
- break;
-
+
default:
val = (OBJECT)Qnil;
}
-
+
return NEW_HANDLE(ctx, val);
}
@@ -1264,7 +1262,7 @@ int rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...) {
void rb_check_type(VALUE x, int t) {
if (TYPE(x) != t) {
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
- rb_obj_classname(x), rb_obj_classname(subtend_get_global(t)));
+ rb_obj_classname(x), rb_class2name(subtend_get_global(t)));
}
}
diff --git a/shotgun/lib/subtend/ruby.h b/shotgun/lib/subtend/ruby.h
index 1a1ca5f..52f98d2 100644
--- a/shotgun/lib/subtend/ruby.h
+++ b/shotgun/lib/subtend/ruby.h
@@ -116,6 +116,9 @@ enum {
T_VARMAP,
T_SCOPE,
T_NODE,
+ T_IO,
+ T_THREAD,
+ T_INTEGER
};
int rb_type(VALUE obj);
@@ -125,24 +128,24 @@ int rb_type(VALUE obj);
* in ruby.c. It is safe to do so, these numbers have no inherent
* meanings.
*/
-#define rb_cObject (subtend_get_global(0))
-#define rb_cArray (subtend_get_global(1))
-#define rb_cBignum (subtend_get_global(2))
-#define rb_cClass (subtend_get_global(3))
-#define rb_cData (subtend_get_global(4))
-#define rb_cFalseClass (subtend_get_global(5))
-#define rb_cFixnum (subtend_get_global(6))
-#define rb_cFloat (subtend_get_global(7))
-#define rb_cHash (subtend_get_global(8))
-#define rb_cIO (subtend_get_global(9))
-#define rb_cModule (subtend_get_global(10))
-#define rb_cNilClass (subtend_get_global(11))
-#define rb_cRegexp (subtend_get_global(12))
-#define rb_cString (subtend_get_global(13))
-#define rb_cSymbol (subtend_get_global(14))
-#define rb_cThread (subtend_get_global(15))
-#define rb_cTrueClass (subtend_get_global(16))
-#define rb_cInteger (subtend_get_global(17))
+#define rb_cObject (subtend_get_global(T_OBJECT))
+#define rb_cArray (subtend_get_global(T_ARRAY))
+#define rb_cBignum (subtend_get_global(T_BIGNUM))
+#define rb_cClass (subtend_get_global(T_CLASS))
+#define rb_cData (subtend_get_global(T_DATA))
+#define rb_cFalseClass (subtend_get_global(T_FALSE))
+#define rb_cFixnum (subtend_get_global(T_FIXNUM))
+#define rb_cFloat (subtend_get_global(T_FLOAT))
+#define rb_cHash (subtend_get_global(T_HASH))
+#define rb_cIO (subtend_get_global(T_IO))
+#define rb_cModule (subtend_get_global(T_MODULE))
+#define rb_cNilClass (subtend_get_global(T_NIL))
+#define rb_cRegexp (subtend_get_global(T_REGEXP))
+#define rb_cString (subtend_get_global(T_STRING))
+#define rb_cSymbol (subtend_get_global(T_SYMBOL))
+#define rb_cThread (subtend_get_global(T_THREAD))
+#define rb_cTrueClass (subtend_get_global(T_TRUE))
+#define rb_cInteger (subtend_get_global(T_INTEGER))
#define rb_mKernel rb_const_get(rb_cObject, rb_intern("Kernel") )
#define rb_mComparable rb_const_get(rb_cObject, rb_intern("Comparable") )
diff --git a/spec/subtend/ext/subtend_object.c b/spec/subtend/ext/subtend_object.c
index 44d6061..9150825 100644
--- a/spec/subtend/ext/subtend_object.c
+++ b/spec/subtend/ext/subtend_object.c
@@ -88,6 +88,31 @@ VALUE so_is_type_class(VALUE self, VALUE obj) {
return Qfalse;
}
+VALUE so_check_type_nil(VALUE self, VALUE obj) {
+ Check_Type(obj, T_NIL);
+ return Qnil;
+}
+
+VALUE so_check_type_object(VALUE self, VALUE obj) {
+ Check_Type(obj, T_OBJECT);
+ return Qnil;
+}
+
+VALUE so_check_type_array(VALUE self, VALUE obj) {
+ Check_Type(obj, T_ARRAY);
+ return Qnil;
+}
+
+VALUE so_check_type_module(VALUE self, VALUE obj) {
+ Check_Type(obj, T_MODULE);
+ return Qnil;
+}
+
+VALUE so_check_type_class(VALUE self, VALUE obj) {
+ Check_Type(obj, T_CLASS);
+ return Qnil;
+}
+
void Init_subtend_object() {
VALUE cls;
cls = rb_define_class("SubtendObject", rb_cObject);
@@ -109,4 +134,10 @@ void Init_subtend_object() {
rb_define_method(cls, "rb_is_type_array", so_is_type_array, 1);
rb_define_method(cls, "rb_is_type_module", so_is_type_module, 1);
rb_define_method(cls, "rb_is_type_class", so_is_type_class, 1);
+
+ rb_define_method(cls, "rb_check_type_nil", so_check_type_nil, 1);
+ rb_define_method(cls, "rb_check_type_object", so_check_type_object, 1);
+ rb_define_method(cls, "rb_check_type_array", so_check_type_array, 1);
+ rb_define_method(cls, "rb_check_type_module", so_check_type_module, 1);
+ rb_define_method(cls, "rb_check_type_class", so_check_type_class, 1);
}
diff --git a/spec/subtend/object_spec.rb b/spec/subtend/object_spec.rb
index a028d90..acf3d1a 100644
--- a/spec/subtend/object_spec.rb
+++ b/spec/subtend/object_spec.rb
@@ -131,4 +131,16 @@ describe "SubtendObject" do
@o.rb_is_type_module(ObjectTest).should == false
@o.rb_is_type_class(ObjectTest).should == true
end
+
+ it "rb_check_type should check the type of a given object raising a TypeError if the type is wrong" do
+ class DescArray < Array
+ end
+ @o.rb_check_type_nil(nil)
+ lambda { @o.rb_check_type_object([]) }.should raise_error(TypeError, /type Array.*expected Object/)
+ @o.rb_check_type_object(ObjectTest.new)
+ @o.rb_check_type_array([])
+ @o.rb_check_type_array(DescArray.new)
+ lambda { @o.rb_check_type_module(ObjectTest) }.should raise_error(TypeError, /type Class.*expected Module/)
+ @o.rb_check_type_class(ObjectTest)
+ end
end
|