From 990d41f9f7f79443d1b2fff2c993fc342b1c5982 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 9 Dec 2022 17:30:17 +0900 Subject: [PATCH] mruby-class-ext: new method `attached_object` introduced in Ruby3.2 --- mrbgems/mruby-class-ext/src/class.c | 30 +++++++++++++++++++++++++++ mrbgems/mruby-class-ext/test/class.rb | 16 ++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/mrbgems/mruby-class-ext/src/class.c b/mrbgems/mruby-class-ext/src/class.c index 141264bb6..dbe061524 100644 --- a/mrbgems/mruby-class-ext/src/class.c +++ b/mrbgems/mruby-class-ext/src/class.c @@ -3,6 +3,8 @@ #include "mruby/string.h" #include "mruby/array.h" #include "mruby/proc.h" +#include "mruby/variable.h" +#include "mruby/presym.h" static mrb_value mrb_mod_name(mrb_state *mrb, mrb_value self) @@ -108,6 +110,33 @@ mrb_class_subclasses(mrb_state *mrb, mrb_value self) return ary; } +/* + * call-seq: + * attached_object -> object + * + * Returns the object for which the receiver is the singleton class. + * Raises an TypeError if the class is not a singleton class. + * + * class Foo; end + * + * Foo.singleton_class.attached_object #=> Foo + * Foo.attached_object #=> TypeError: not a singleton class + * Foo.new.singleton_class.attached_object #=> # + * TrueClass.attached_object #=> TypeError: not a singleton class + * NilClass.attached_object #=> TypeError: not a singleton class + */ +static mrb_value +mrb_class_attached_object(mrb_state *mrb, mrb_value self) +{ + struct RClass *c; + + c = mrb_class_ptr(self); + if (c->tt != MRB_TT_SCLASS) { + mrb_raise(mrb, E_TYPE_ERROR, "not a singleton class"); + } + return mrb_obj_iv_get(mrb, (struct RObject*)c, MRB_SYM(__attached__)); +} + void mrb_mruby_class_ext_gem_init(mrb_state *mrb) { @@ -120,6 +149,7 @@ mrb_mruby_class_ext_gem_init(mrb_state *mrb) struct RClass *cls = mrb->class_class; mrb_define_method(mrb, cls, "subclasses", mrb_class_subclasses, MRB_ARGS_NONE()); + mrb_define_method(mrb, cls, "attached_object", mrb_class_attached_object, MRB_ARGS_NONE()); } void diff --git a/mrbgems/mruby-class-ext/test/class.rb b/mrbgems/mruby-class-ext/test/class.rb index 2043b39cb..fba2a19f9 100644 --- a/mrbgems/mruby-class-ext/test/class.rb +++ b/mrbgems/mruby-class-ext/test/class.rb @@ -11,3 +11,19 @@ assert 'Class#subclasses' do assert_equal([c], b.subclasses) assert_equal([], c.subclasses) end + +assert 'Class#attached_object' do + foo = Class.new + foo_s = class <