4 static MGVTBL mop_attr_vtbl;
7 mop_attr_mg(pTHX_ SV* const attr, SV* const instance){
11 croak("Invalid Attribute object");
15 mg_obj: meta information (AV*)
16 mg_ptr: meta instance virtual table (mop_instance_vtbl*)
19 if(!(SvMAGICAL(SvRV(attr)) && (mg = mop_mg_find(aTHX_ SvRV(attr), &mop_attr_vtbl, 0))) ) {
21 AV* const meta = newAV();
25 mg = sv_magicext(SvRV(attr), (SV*)meta, PERL_MAGIC_ext, &mop_attr_vtbl, NULL, 0);
27 av_extend(meta, MOP_ATTR_last - 1);
32 name = mop_call0(aTHX_ attr, mop_name);
33 av_store(meta, MOP_ATTR_SLOT, newSVsv_share(name));
35 if(SvOK( sv = mop_call0_pvs(attr, "init_arg") )) {
36 flags |= MOP_ATTRf_HAS_INIT_ARG;
38 av_store(meta, MOP_ATTR_INIT_ARG, newSVsv_share(sv));
41 /* NOTE: Setting both default and builder is not allowed */
42 if(SvOK( sv = mop_call0_pvs(attr, "builder") )) {
43 SV* const builder = sv;
44 flags |= MOP_ATTRf_HAS_BUILDER;
46 if(SvOK( sv = mop_call1(aTHX_ instance, mop_can, builder) )){
47 av_store(meta, MOP_ATTR_BUILDER, newSVsv(sv));
50 croak("%s does not support builder method '%"SVf"' for attribute '%"SVf"'",
51 sv_reftype(SvRV(instance), TRUE), builder, name);
54 else if(SvOK( sv = mop_call0_pvs(attr, "default") )) {
55 if(SvTRUEx( mop_call0_pvs(attr, "is_default_a_coderef") )){
56 flags |= MOP_ATTRf_HAS_BUILDER;
57 av_store(meta, MOP_ATTR_BUILDER, newSVsv(sv));
60 flags |= MOP_ATTRf_HAS_DEFAULT;
61 av_store(meta, MOP_ATTR_DEFAULT, newSVsv(sv));
65 MOP_mg_flags(mg) = flags;
67 if(flags & MOP_ATTRf_DEBUG) {
68 warn("%s: setup attr_mg for '%"SVf"'\n", sv_reftype(SvRV(instance), TRUE), name);
79 mop_attr_initialize_instance_slot(pTHX_ SV* const attr, const mop_instance_vtbl* const vtbl, SV* const instance, HV* const args){
80 MAGIC* const mg = mop_attr_mg(aTHX_ attr, instance);
81 AV* const meta = (AV*)MOP_mg_obj(mg);
82 U16 const flags = MOP_mg_flags(mg);
86 if(flags & MOP_ATTRf_DEBUG){
87 warn("%s: initialize_instance_slot '%"SVf"' (0x%04x)\n", sv_reftype(SvRV(instance), TRUE), MOP_attr_slot(meta), (unsigned)flags);
90 if( flags & MOP_ATTRf_HAS_INIT_ARG && (arg = hv_fetch_ent(args, MOP_attr_init_arg(meta), FALSE, 0U)) ){
91 value = hv_iterval(args, arg);
93 else if(flags & MOP_ATTRf_HAS_DEFAULT) {
94 value = MOP_attr_default(meta); /* it's always a non-ref value */
96 else if(flags & MOP_ATTRf_HAS_BUILDER) {
97 SV* const builder = MOP_attr_builder(meta); /* code-ref default value or builder */
107 call_sv(builder, G_SCALAR);
111 SvREFCNT_inc_simple_void_NN(value);
124 if(flags & MOP_ATTRf_HAS_INITIALIZER){
125 /* $attr->set_initial_value($meta_instance, $instance, $value) */
135 call_method("set_initial_value", G_VOID | G_DISCARD);
138 vtbl->set_slot(aTHX_ NULL, instance, MOP_attr_slot(meta), value);
144 MODULE = Class::MOP::Attribute PACKAGE = Class::MOP::Attribute
148 VERSIONCHECK: DISABLE
151 INSTALL_SIMPLE_READER(Attribute, name);
152 INSTALL_SIMPLE_READER(Attribute, associated_class);
153 INSTALL_SIMPLE_READER(Attribute, associated_methods);
154 INSTALL_SIMPLE_READER(Attribute, accessor);
155 INSTALL_SIMPLE_READER(Attribute, reader);
156 INSTALL_SIMPLE_READER(Attribute, writer);
157 INSTALL_SIMPLE_READER(Attribute, predicate);
158 INSTALL_SIMPLE_READER(Attribute, clearer);
159 INSTALL_SIMPLE_READER(Attribute, builder);
160 INSTALL_SIMPLE_READER(Attribute, init_arg);
161 INSTALL_SIMPLE_READER(Attribute, initializer);
162 INSTALL_SIMPLE_READER(Attribute, insertion_order);
163 INSTALL_SIMPLE_READER(Attribute, definition_context);
165 INSTALL_SIMPLE_WRITER_WITH_KEY(Attribute, _set_insertion_order, insertion_order);
167 INSTALL_SIMPLE_PREDICATE(Attribute, accessor);
168 INSTALL_SIMPLE_PREDICATE(Attribute, reader);
169 INSTALL_SIMPLE_PREDICATE(Attribute, writer);
170 INSTALL_SIMPLE_PREDICATE(Attribute, predicate);
171 INSTALL_SIMPLE_PREDICATE(Attribute, clearer);
172 INSTALL_SIMPLE_PREDICATE(Attribute, builder);
173 INSTALL_SIMPLE_PREDICATE(Attribute, init_arg);
174 INSTALL_SIMPLE_PREDICATE(Attribute, initializer);
175 INSTALL_SIMPLE_PREDICATE(Attribute, default);