diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index 8171ab3..ebe3ebb 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -1527,14 +1527,17 @@ NORETURN(void rb_throw_obj(VALUE,VALUE)); VALUE rb_require(const char*); +RUBY_EXTERN VALUE rb_mBool; RUBY_EXTERN VALUE rb_mKernel; RUBY_EXTERN VALUE rb_mComparable; RUBY_EXTERN VALUE rb_mEnumerable; RUBY_EXTERN VALUE rb_mErrno; +RUBY_EXTERN VALUE rb_mFalse; RUBY_EXTERN VALUE rb_mFileTest; RUBY_EXTERN VALUE rb_mGC; RUBY_EXTERN VALUE rb_mMath; RUBY_EXTERN VALUE rb_mProcess; +RUBY_EXTERN VALUE rb_mTrue; RUBY_EXTERN VALUE rb_mWaitReadable; RUBY_EXTERN VALUE rb_mWaitWritable; diff --git a/object.c b/object.c index 3126ed0..870583c 100644 --- a/object.c +++ b/object.c @@ -33,8 +33,11 @@ VALUE rb_cClass; VALUE rb_cData; VALUE rb_cNilClass; +VALUE rb_mBool; VALUE rb_cTrueClass; VALUE rb_cFalseClass; +VALUE rb_mTrue; +VALUE rb_mFalse; #define id_eq idEq #define id_eql idEqlP @@ -1386,6 +1389,66 @@ rb_false(VALUE obj) return Qfalse; } +static VALUE +rb_bool_append_features(VALUE module, VALUE includeto) +{ + if ((includeto != rb_cFalseClass) && (includeto != rb_cTrueClass)) { + rb_raise(rb_eTypeError, "'%s' isn't FalseClass nor TrueClass", + rb_class2name(includeto)); + } + + return module; +} + +/* + * call-seq: + * False === nil -> true + * False === false -> true + * False === true -> false + * False === -> false + * + * Only the objects nil and false respond true. + * Others respond false. + */ + +static VALUE +rb_false_rtest(VALUE obj1, VALUE obj2) +{ + VALUE result; + + result = rb_funcall(obj2, id_eq, 1, Qnil); + if (RTEST(result)) return Qtrue; + + result = rb_funcall(obj2, id_eq, 1, Qfalse); + if (RTEST(result)) return Qtrue; + + return Qfalse; +} + +/* + * call-seq: + * True === nil -> false + * True === false -> false + * True === true -> true + * True === -> true + * + * Only the objects nil and false respond false. + * Others respond true. + */ + +static VALUE +rb_true_rtest(VALUE obj1, VALUE obj2) +{ + VALUE result; + + result = rb_funcall(obj2, id_eq, 1, Qnil); + if (!RTEST(result)) { + result = rb_funcall(obj2, id_eq, 1, Qfalse); + if (!RTEST(result)) return Qtrue; + } + + return Qfalse; +} /* * call-seq: @@ -3445,7 +3508,11 @@ Init_Object(void) rb_cData = rb_define_class("Data", rb_cObject); rb_undef_alloc_func(rb_cData); + rb_mBool = rb_define_module("Bool"); + rb_define_singleton_method(rb_mBool, "append_features", rb_bool_append_features, 1); + rb_cTrueClass = rb_define_class("TrueClass", rb_cObject); + rb_include_module(rb_cTrueClass, rb_mBool); rb_define_method(rb_cTrueClass, "to_s", true_to_s, 0); rb_define_alias(rb_cTrueClass, "inspect", "to_s"); rb_define_method(rb_cTrueClass, "&", true_and, 1); @@ -3459,6 +3526,7 @@ Init_Object(void) rb_define_global_const("TRUE", Qtrue); rb_cFalseClass = rb_define_class("FalseClass", rb_cObject); + rb_include_module(rb_cFalseClass, rb_mBool); rb_define_method(rb_cFalseClass, "to_s", false_to_s, 0); rb_define_alias(rb_cFalseClass, "inspect", "to_s"); rb_define_method(rb_cFalseClass, "&", false_and, 1); @@ -3470,4 +3538,16 @@ Init_Object(void)