Project

General

Profile

Feature #6682 ยป class_singleton_instance.patch

zzak (zzak _), 11/19/2012 08:43 AM

View differences:

NEWS
* extended method:
* Module#define_method accepts a UnboundMethod from a Module.
* Class
* added method:
* added Class#singleton_instance returning the attached instance from a
singleton Class. This is the reversed version of the
Kernel#singleton_class getter method.
* NilClass
* added method:
* added nil.to_h which returns {}
class.c
return Qnil;
}
static inline VALUE
special_singleton_instance_of(VALUE obj)
{
SPECIAL_SINGLETON(rb_cNilClass, Qnil);
SPECIAL_SINGLETON(rb_cFalseClass, Qfalse);
SPECIAL_SINGLETON(rb_cTrueClass, Qtrue);
rb_raise(rb_eTypeError, "not singleton class");
}
VALUE
rb_special_singleton_class(VALUE obj)
{
return special_singleton_class_of(obj);
}
VALUE
rb_special_singleton_instance(VALUE obj)
{
return special_singleton_instance_of(obj);
}
/*!
* \internal
* Returns the singleton class of \a obj. Creates it if necessary.
internal.h
VALUE rb_obj_public_methods(int argc, VALUE *argv, VALUE obj);
int rb_obj_basic_to_s_p(VALUE);
VALUE rb_special_singleton_class(VALUE);
VALUE rb_special_singleton_instance(VALUE);
void Init_class_hierarchy(void);
/* compile.c */
object.c
return super;
}
/*
* call-seq:
* class.singleton_instance -> an_object
*
* Returns the attached singleton instance of <i>class</i>.
*
* klass = "Hello".singleton_class
* klass.singleton_instance => "Hello"
*
* If the given class isn't a singleton class, it raises a TypeError.
*
*/
VALUE
rb_class_singleton_instance(VALUE klass)
{
if(FL_TEST(klass, FL_SINGLETON)) {
return rb_iv_get(klass, "__attached__");
} else {
return rb_special_singleton_instance(klass);
}
}
VALUE
rb_class_get_superclass(VALUE klass)
{
......
rb_define_method(rb_cClass, "initialize", rb_class_initialize, -1);
rb_define_method(rb_cClass, "initialize_copy", rb_class_init_copy, 1); /* in class.c */
rb_define_method(rb_cClass, "superclass", rb_class_superclass, 0);
rb_define_method(rb_cClass, "singleton_instance", rb_class_singleton_instance, 0);
rb_define_alloc_func(rb_cClass, rb_class_s_alloc);
rb_undef_method(rb_cClass, "extend_object");
rb_undef_method(rb_cClass, "append_features");
test/ruby/test_class.rb
INPUT
end
def test_singleton_instance
o = Object.new
c = o.singleton_class
assert_equal(o, c.singleton_instance)
end
def test_no_singleton_instance
assert_raise(TypeError) { String.singleton_instance }
end
def test_class_singleton_instance
c = Object.singleton_class
assert_equal(Object, c.singleton_instance)
end
def test_immediate_singleton_instance
assert_equal(true, TrueClass.singleton_instance)
assert_equal(false, FalseClass.singleton_instance)
assert_equal(nil, NilClass.singleton_instance)
end
def test_uninitialized
assert_raise(TypeError) { Class.allocate.new }
assert_raise(TypeError) { Class.allocate.superclass }
    (1-1/1)