Add new function `mrb_singleton_class_ptr()`; ref #4973

The difference between `mrb_singleton_class` and `mrb_singleton_class_ptr`:

- `mrb_singleton_class_ptr` returns `struct RClass*`.
- `mrb_singleton_class_ptr` returns `NULL` on immediate values where
  `mrb_singleton_class` raises exceptions.
parent 2e661e82
...@@ -317,7 +317,9 @@ MRB_API struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct ...@@ -317,7 +317,9 @@ MRB_API struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct
* @return [struct RClass *] Reference to the newly defined module. * @return [struct RClass *] Reference to the newly defined module.
*/ */
MRB_API struct RClass *mrb_define_module(mrb_state *mrb, const char *name); MRB_API struct RClass *mrb_define_module(mrb_state *mrb, const char *name);
MRB_API mrb_value mrb_singleton_class(mrb_state *mrb, mrb_value val); MRB_API mrb_value mrb_singleton_class(mrb_state *mrb, mrb_value val);
MRB_API struct RClass *mrb_singleton_class_ptr(mrb_state *mrb, mrb_value val);
/** /**
* Include a module in another class or module. * Include a module in another class or module.
......
...@@ -1242,33 +1242,45 @@ mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod) ...@@ -1242,33 +1242,45 @@ mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod)
return mod; return mod;
} }
MRB_API mrb_value /* returns mrb_class_ptr(mrb_singleton_class()) */
mrb_singleton_class(mrb_state *mrb, mrb_value v) /* except that it return NULL for immediate values */
MRB_API struct RClass*
mrb_singleton_class_ptr(mrb_state *mrb, mrb_value v)
{ {
struct RBasic *obj; struct RBasic *obj;
switch (mrb_type(v)) { switch (mrb_type(v)) {
case MRB_TT_FALSE: case MRB_TT_FALSE:
if (mrb_nil_p(v)) if (mrb_nil_p(v))
return mrb_obj_value(mrb->nil_class); return mrb->nil_class;
return mrb_obj_value(mrb->false_class); return mrb->false_class;
case MRB_TT_TRUE: case MRB_TT_TRUE:
return mrb_obj_value(mrb->true_class); return mrb->true_class;
case MRB_TT_CPTR: case MRB_TT_CPTR:
return mrb_obj_value(mrb->object_class); return mrb->object_class;
case MRB_TT_SYMBOL: case MRB_TT_SYMBOL:
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
#ifndef MRB_WITHOUT_FLOAT #ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
#endif #endif
mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton"); return NULL;
return mrb_nil_value(); /* not reached */
default: default:
break; break;
} }
obj = mrb_basic_ptr(v); obj = mrb_basic_ptr(v);
prepare_singleton_class(mrb, obj); prepare_singleton_class(mrb, obj);
return mrb_obj_value(obj->c); return obj->c;
}
MRB_API mrb_value
mrb_singleton_class(mrb_state *mrb, mrb_value v)
{
struct RClass *c = mrb_singleton_class_ptr(mrb, v);
if (c == NULL) {
mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton");
}
return mrb_obj_value(c);
} }
MRB_API void MRB_API void
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment