void rb_attr(VALUE klass, ID id, int read, int write, int ex) { const char *name; ID attriv; VALUE aname; int noex; if (!ex) { noex = NOEX_PUBLIC; } else { if (SCOPE_TEST(NOEX_PRIVATE)) { noex = NOEX_PRIVATE; rb_warning((SCOPE_CHECK(NOEX_MODFUNC)) ? "attribute accessor as module_function" : "private attribute?"); } else if (SCOPE_TEST(NOEX_PROTECTED)) { noex = NOEX_PROTECTED; } else { noex = NOEX_PUBLIC; } } if (!rb_is_local_id(id) && !rb_is_const_id(id)) { rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id)); } name = rb_id2name(id); if (!name) { rb_raise(rb_eArgError, "argument needs to be symbol or string"); } aname = rb_sprintf("@%s", name); rb_enc_copy(aname, rb_id2str(id)); attriv = rb_intern_str(aname); if (read) { rb_add_method(klass, id, NEW_IVAR(attriv), noex); } if (write) { rb_add_method(klass, rb_id_attrset(id), NEW_ATTRSET(attriv), noex); } }
void rb_attr(VALUE klass, ID id, int read, int write, int ex) { VALUE attriv; VALUE aname; rb_method_flag_t noex; if (!ex) { noex = NOEX_PUBLIC; } else { if (SCOPE_TEST(NOEX_PRIVATE)) { noex = NOEX_PRIVATE; rb_warning((SCOPE_CHECK(NOEX_MODFUNC)) ? "attribute accessor as module_function" : "private attribute?"); } else if (SCOPE_TEST(NOEX_PROTECTED)) { noex = NOEX_PROTECTED; } else { noex = NOEX_PUBLIC; } } aname = rb_id2str(rb_check_attr_id(id)); if (NIL_P(aname)) { rb_raise(rb_eArgError, "argument needs to be symbol or string"); } attriv = (VALUE)rb_intern_str(rb_sprintf("@%"PRIsVALUE, aname)); if (read) { rb_add_method(klass, id, VM_METHOD_TYPE_IVAR, (void *)attriv, noex); } if (write) { rb_add_method(klass, rb_id_attrset(id), VM_METHOD_TYPE_ATTRSET, (void *)attriv, noex); } }