Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Define Class#singleton_instance #142

Closed
wants to merge 1 commit into from

2 participants

@ryoqun

Hi, I defined a new instance method for Class. It's called singleton_instance. It returns the attached instance from a singleton Class. In short, it's the reversed version of the Kernel#singleton_class getter method.

This pull request has a corresponding issue on Ruby Issue Tracking System: https://bugs.ruby-lang.org/issues/6682

@shyouhei shyouhei referenced this pull request from a commit
kanemoto avoid compilation error on AIX by -ansi -std=iso9899:199409 (r36038).…
… [ruby-core:46744] [Bug #6791].

This issue is fixed in upper stream as issue #142. (flori/json#142)



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36541 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
48cb947
@tenderlove tenderlove referenced this pull request from a commit
kanemoto avoid compilation error on AIX by -ansi -std=iso9899:199409 (r36038).…
… [ruby-core:46744] [Bug #6791].

This issue is fixed in upper stream as issue #142. (flori/json#142)



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36541 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
77af3c6
@zzak
Collaborator

Closing this, please refer to Feature #6682 on redmine

@zzak zzak closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 25, 2012
  1. @ryoqun
This page is out of date. Refresh to see the latest.
View
6 NEWS
@@ -62,6 +62,12 @@ with all sufficient information, see the ChangeLog file.
* 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 {}
View
15 class.c
@@ -1294,12 +1294,27 @@ special_singleton_class_of(VALUE obj)
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.
View
1  internal.h
@@ -62,6 +62,7 @@ VALUE rb_obj_private_methods(int argc, VALUE *argv, VALUE obj);
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 */
View
24 object.c
@@ -1744,6 +1744,29 @@ rb_class_superclass(VALUE klass)
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)
{
@@ -2989,6 +3012,7 @@ Init_Object(void)
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");
View
21 test/ruby/test_class.rb
@@ -206,6 +206,27 @@ module Foo; def foo; :foo; end; end
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 }
Something went wrong with that request. Please try again.