X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=xs-src%2FMouse.xs;h=19d98c6eba6dd49d6e51c3e39e67a120a4b3a92d;hb=fcdc12ac0d67969cf79745b062fd706ae56c8b92;hp=5c7e623ae294478ff798e1bf0a2b23a144232309;hpb=60cd9f19cf891bd7bff4ca33efa71bb3e95f0cb9;p=gitmo%2FMouse.git diff --git a/xs-src/Mouse.xs b/xs-src/Mouse.xs index 5c7e623..19d98c6 100644 --- a/xs-src/Mouse.xs +++ b/xs-src/Mouse.xs @@ -338,13 +338,15 @@ mouse_class_initialize_object(pTHX_ SV* const meta, SV* const object, HV* const } used++; } - else if(!is_cloning){ /* no init arg, noop while cloning */ + else { /* no init arg */ if(flags & (MOUSEf_ATTR_HAS_DEFAULT | MOUSEf_ATTR_HAS_BUILDER)){ - if(!(flags & MOUSEf_ATTR_IS_LAZY)){ + /* skip if the object has the slot (it occurs on cloning/reblessing) */ + if(!(flags & MOUSEf_ATTR_IS_LAZY) && !has_slot(object, slot)){ mouse_xa_set_default(aTHX_ xa, object); } } - else if(flags & MOUSEf_ATTR_IS_REQUIRED) { + /* don't check while cloning (or reblesseing) */ + else if(!is_cloning && flags & MOUSEf_ATTR_IS_REQUIRED) { mouse_throw_error(attr, NULL, "Attribute (%"SVf") is required", slot); } } @@ -569,18 +571,40 @@ PPCODE: } } -SV* +void new_object(SV* meta, ...) CODE: { AV* const xc = mouse_get_xc(aTHX_ meta); HV* const args = mouse_buildargs(aTHX_ meta, NULL, ax, items); + SV* object; - RETVAL = mouse_instance_create(aTHX_ MOUSE_xc_stash(xc)); - mouse_class_initialize_object(aTHX_ meta, RETVAL, args, FALSE); + object = mouse_instance_create(aTHX_ MOUSE_xc_stash(xc)); + mouse_class_initialize_object(aTHX_ meta, object, args, FALSE); + mouse_buildall(aTHX_ xc, object, sv_2mortal(newRV_inc((SV*)args))); /* BUILDALL */ + ST(0) = object; /* because object is mortal, we should return it as is */ + XSRETURN(1); +} + +void +clone_object(SV* meta, SV* object, ...) +CODE: +{ + AV* const xc = mouse_get_xc(aTHX_ meta); + HV* const args = mouse_buildargs(aTHX_ meta, NULL, ax + 1, items - 1); + SV* proto; + + if(!mouse_is_an_instance_of(aTHX_ MOUSE_xc_stash(xc), object)) { + mouse_throw_error(meta, object, + "You must pass an instance of the metaclass (%"SVf"), not (%"SVf")", + mcall0(meta, mouse_name), object); + } + + proto = mouse_instance_clone(aTHX_ object); + mouse_class_initialize_object(aTHX_ meta, proto, args, TRUE); + ST(0) = proto; /* because object is mortal, we should return it as is */ + XSRETURN(1); } -OUTPUT: - RETVAL void _initialize_object(SV* meta, SV* object, HV* args, bool is_cloning = FALSE) @@ -632,7 +656,7 @@ PPCODE: MODULE = Mouse PACKAGE = Mouse::Object -SV* +void new(SV* klass, ...) CODE: { @@ -640,6 +664,7 @@ CODE: AV* const xc = mouse_get_xc(aTHX_ meta); UV const flags = MOUSE_xc_flags(xc); SV* args; + SV* object; /* BUILDARGS */ if(flags & MOUSEf_XC_HAS_BUILDARGS){ @@ -669,13 +694,12 @@ CODE: } /* new_object */ - RETVAL = mouse_instance_create(aTHX_ MOUSE_xc_stash(xc)); - mouse_class_initialize_object(aTHX_ meta, RETVAL, (HV*)SvRV(args), FALSE); - - mouse_buildall(aTHX_ xc, RETVAL, args); + object = mouse_instance_create(aTHX_ MOUSE_xc_stash(xc)); + mouse_class_initialize_object(aTHX_ meta, object, (HV*)SvRV(args), FALSE); + mouse_buildall(aTHX_ xc, object, args); /* BUILDALL */ + ST(0) = object; /* because object is mortal, we should return it as is */ + XSRETURN(1); } -OUTPUT: - RETVAL void DESTROY(SV* object)