#define get_slots(self, key) get_slot(self, sv_2mortal(newSVpvs_share(key)))
#define set_slots(self, key, value) set_slot(self, sv_2mortal(newSVpvs_share(key)), value)
-/* mouse_simle_accessor.xs */
+/* mouse_simle_accessor.xs for meta object protocols */
#define INSTALL_SIMPLE_READER(klass, name) \
INSTALL_SIMPLE_READER_WITH_KEY(klass, name, name)
#define INSTALL_SIMPLE_READER_WITH_KEY(klass, name, key) \
- (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::" #klass "::" #name, #key, sizeof(#key)-1, XS_Mouse_simple_reader, NULL, 0)
+ (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::" #klass "::" \
+ #name, #key, sizeof(#key)-1, XS_Mouse_simple_reader, NULL, 0)
#define INSTALL_CLASS_HOLDER_SV(klass, name, dsv) \
- (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::" #klass "::" #name, #name, sizeof(#name)-1, XS_Mouse_simple_reader, (dsv), HEf_SVKEY)
+ (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::" #klass "::" \
+ #name, #name, sizeof(#name)-1, XS_Mouse_simple_reader, (dsv), HEf_SVKEY)
#define INSTALL_CLASS_HOLDER(klass, name, ds) \
INSTALL_CLASS_HOLDER_SV(klass, name, newSVpvs(ds))
#define INSTALL_SIMPLE_WRITER(klass, name) \
NSTALL_SIMPLE_WRITER_WITH_KEY(klass, name, name)
#define INSTALL_SIMPLE_WRITER_WITH_KEY(klass, name, key) \
- (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::" #klass "::" #name, #key, sizeof(#key)-1, XS_Mouse_simple_writer, NULL, 0)
+ (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::" #klass "::" \
+ #name, #key, sizeof(#key)-1, XS_Mouse_simple_writer, NULL, 0)
#define INSTALL_SIMPLE_PREDICATE(klass, name) \
INSTALL_SIMPLE_PREDICATE_WITH_KEY(klass, name, name)
#define INSTALL_SIMPLE_PREDICATE_WITH_KEY(klass, name, key) \
- (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::" #klass "::" #name, #key, sizeof(#key)-1, XS_Mouse_simple_predicate, NULL, 0)
+ (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::" #klass "::" \
+ #name, #key, sizeof(#key)-1, XS_Mouse_simple_predicate, NULL, 0)
+
+/* generate inhertiable class accessors for Mouse::Meta::Class */
+#define INSTALL_INHERITABLE_CLASS_ACCESSOR(name) \
+ INSTALL_INHERITABLE_CLASS_ACCESSOR_WITH_KEY(name, name)
+#define INSTALL_INHERITABLE_CLASS_ACCESSOR_WITH_KEY(name, key) \
+ (void)mouse_simple_accessor_generate(aTHX_ "Mouse::Meta::Class::" #name,\
+ #key, sizeof(#key)-1, XS_Mouse_inheritable_class_accessor, NULL, 0)
CV* mouse_simple_accessor_generate(pTHX_ const char* const fq_name, const char* const key, I32 const keylen, XSUBADDR_t const accessor_impl, void* const dptr, I32 const dlen);
XS(XS_Mouse_reader);
XS(XS_Mouse_writer);
+XS(XS_Mouse_inheritable_class_accessor);
+
/* type constraints */
int mouse_tc_check(pTHX_ SV* const tc, SV* const sv);
INSTALL_SIMPLE_PREDICATE_WITH_KEY(Class, is_anon_class, anon_serial_id);
INSTALL_SIMPLE_READER(Class, is_immutable);
+ INSTALL_INHERITABLE_CLASS_ACCESSOR(strict_constructor);
+
INSTALL_CLASS_HOLDER(Class, method_metaclass, "Mouse::Meta::Method");
INSTALL_CLASS_HOLDER(Class, attribute_metaclass, "Mouse::Meta::Attribute");
INSTALL_CLASS_HOLDER(Class, constructor_class, "Mouse::Meta::Method::Constructor::XS");
mouse_class_initialize_object(aTHX_ meta, object, args, is_cloning);
}
-void
-strict_constructor(SV* self, SV* value = NULL)
-CODE:
-{
- SV* const slot = sv_2mortal(newSVpvs_share("strict_constructor"));
- SV* const stash_ref = mcall0(self, mouse_namespace);
- HV* stash;
-
- if(!(SvROK(stash_ref) && SvTYPE(SvRV(stash_ref)) == SVt_PVHV)) {
- croak("namespace() didn't return a HASH reference");
- }
- stash = (HV*)SvRV(stash_ref);
-
- if(value) { /* setter */
- set_slot(self, slot, value);
- mro_method_changed_in(stash);
- }
-
- value = get_slot(self, slot);
-
- if(!value) {
- AV* const isa = mro_get_linear_isa(stash);
- I32 const len = av_len(isa) + 1;
- I32 i;
- for(i = 1; i < len; i++) {
- SV* const klass = MOUSE_av_at(isa, i);
- SV* const meta = get_metaclass(klass);
- if(!SvOK(meta)){
- continue; /* skip non-Mouse classes */
- }
- value = get_slot(meta, slot);
- if(value) {
- break;
- }
- }
- }
- ST(0) = value ? value : &PL_sv_no;
-}
-
MODULE = Mouse PACKAGE = Mouse::Meta::Role
BOOT:
}
else{
mouse_throw_error(MOUSE_mg_attribute(mg), NULL,
- "Expected exactly one or two argument for an accessor");
+ "Expected exactly one or two argument for an accessor of %"SVf,
+ MOUSE_mg_slot(mg));
}
}
if (items != 1) {
mouse_throw_error(MOUSE_mg_attribute(mg), NULL,
- "Cannot assign a value to a read-only accessor");
+ "Cannot assign a value to a read-only accessor of %"SVf,
+ MOUSE_mg_slot(mg));
}
SP -= items; /* PPCODE */
if (items != 2) {
mouse_throw_error(MOUSE_mg_attribute(mg), NULL,
- "Too few arguments for a write-only accessor");
+ "Too few arguments for a write-only accessor of %"SVf,
+ MOUSE_mg_slot(mg));
}
SP -= items; /* PPCODE */
*/
CV*
-mouse_simple_accessor_generate(pTHX_ const char* const fq_name, const char* const key, I32 const keylen, XSUBADDR_t const accessor_impl, void* const dptr, I32 const dlen){
+mouse_simple_accessor_generate(pTHX_
+ const char* const fq_name, const char* const key, I32 const keylen,
+ XSUBADDR_t const accessor_impl, void* const dptr, I32 const dlen) {
CV* const xsub = newXS((char*)fq_name, accessor_impl, __FILE__);
SV* const slot = newSVpvn_share(key, keylen, 0U);
MAGIC* mg;
SV* value;
if (items != 1) {
- croak("Expected exactly one argument for a reader for '%"SVf"'", MOUSE_mg_slot(mg));
+ croak("Expected exactly one argument for a reader of %"SVf,
+ MOUSE_mg_slot(mg));
}
value = get_slot(self, MOUSE_mg_slot(mg));
SV* const slot = MOUSE_mg_slot((MAGIC*)XSANY.any_ptr);
if (items != 2) {
- croak("Expected exactly two argument for a writer for '%"SVf"'", slot);
+ croak("Expected exactly two argument for a writer of %"SVf,
+ slot);
}
ST(0) = set_slot(self, slot, ST(1));
SV* value;
if (items != 1) {
- croak("Expected exactly one argument for a clearer for '%"SVf"'", slot);
+ croak("Expected exactly one argument for a clearer of %"SVf,
+ slot);
}
value = delete_slot(self, slot);
SV* const slot = MOUSE_mg_slot((MAGIC*)XSANY.any_ptr);
if (items != 1) {
- croak("Expected exactly one argument for a predicate for '%"SVf"'", slot);
+ croak("Expected exactly one argument for a predicate of %"SVf, slot);
}
ST(0) = boolSV( has_slot(self, slot) );
XSRETURN(1);
}
+/* Class::Data::Inheritable-like class accessor */
+XS(XS_Mouse_inheritable_class_accessor) {
+ dVAR; dXSARGS;
+ dMOUSE_self;
+ SV* const slot = MOUSE_mg_slot((MAGIC*)XSANY.any_ptr);
+ SV* value;
+ SV* stash_ref;
+ HV* stash;
+
+ if(items == 1){ /* reader */
+ value = NULL;
+ }
+ else if (items == 2){ /* writer */
+ value = ST(1);
+ }
+ else{
+ croak("Expected exactly one or two argument for a class data accessor"
+ "of %"SVf, slot);
+ value = NULL; /* -Wuninitialized */
+ }
+
+ stash_ref= mcall0(self, mouse_namespace);
+ if(!(SvROK(stash_ref) && SvTYPE(SvRV(stash_ref)) == SVt_PVHV)) {
+ croak("namespace() didn't return a HASH reference");
+ }
+ stash = (HV*)SvRV(stash_ref);
+
+ if(!value) { /* reader */
+ value = get_slot(self, slot);
+ if(!value) {
+ AV* const isa = mro_get_linear_isa(stash);
+ I32 const len = av_len(isa) + 1;
+ I32 i;
+ for(i = 1; i < len; i++) {
+ SV* const klass = MOUSE_av_at(isa, i);
+ SV* const meta = get_metaclass(klass);
+ if(!SvOK(meta)){
+ continue; /* skip non-Mouse classes */
+ }
+ value = get_slot(meta, slot);
+ if(value) {
+ break;
+ }
+ }
+ if(!value) {
+ value = &PL_sv_undef;
+ }
+ }
+ }
+ else { /* writer */
+ set_slot(self, slot, value);
+ mro_method_changed_in(stash);
+ }
+
+ ST(0) = value;
+ XSRETURN(1);
+}
+
/* simple instance slot accessor (or Mouse::Meta::Instance) */
SV*