Object-Pad-FieldAttr-LazyInit
view release on metacpan or search on metacpan
lib/Object/Pad/FieldAttr/LazyInit.xs view on Meta::CPAN
if(mg->mg_flags & MGf_REFCOUNTED)
SvREFCNT_dec(mg->mg_obj);
}
}
}
#endif
static int magic_get(pTHX_ SV *sv, MAGIC *mg);
static int magic_set(pTHX_ SV *sv, MAGIC *mg);
static const MGVTBL vtbl = {
.svt_get = &magic_get,
.svt_set = &magic_set,
};
static int magic_get(pTHX_ SV *sv, MAGIC *mg)
{
SV *self = mg->mg_obj;
SV *methodname = (SV *)mg->mg_ptr;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
PUSHs(self);
PUTBACK;
call_method(SvPV_nolen(methodname), G_SCALAR);
SPAGAIN;
SV *value = POPs;
sv_setsv_nomg(sv, value);
FREETMPS;
LEAVE;
/* Now disarm the magic so it won't run again */
mg_freeext(sv, PERL_MAGIC_ext, &vtbl);
return 1;
}
static int magic_set(pTHX_ SV *sv, MAGIC *mg)
{
if(SvROK(sv) && SvRV(sv) == unassigned_val)
/* This is just the constructor applying the default unassigned value;
* don't disarm the magic yet
*/
return 1;
/* Now disarm the magic so it won't run again */
mg_freeext(sv, PERL_MAGIC_ext, &vtbl);
return 1;
}
static bool lazyinit_apply(pTHX_ FieldMeta *fieldmeta, SV *value, SV **attrdata_ptr, void *_funcdata)
{
mop_field_set_default_sv(fieldmeta, newRV_inc(unassigned_val));
return TRUE;
}
static void lazyinit_post_makefield(pTHX_ FieldMeta *fieldmeta, SV *attrdata, void *_funcdata, SV *field)
{
SV *weakself = newSVsv(PAD_SVl(PADIX_SELF));
sv_rvweaken(weakself);
sv_magicext(field, weakself, PERL_MAGIC_ext, &vtbl, (char *)attrdata, HEf_SVKEY);
SvREFCNT_dec(weakself);
}
static const struct FieldHookFuncs lazyinit_hooks = {
.ver = OBJECTPAD_ABIVERSION,
.flags = OBJECTPAD_FLAG_ATTR_MUST_VALUE,
.permit_hintkey = "Object::Pad::FieldAttr::LazyInit/LazyInit",
.apply = &lazyinit_apply,
.post_makefield = &lazyinit_post_makefield,
};
MODULE = Object::Pad::FieldAttr::LazyInit PACKAGE = Object::Pad::FieldAttr::LazyInit
BOOT:
register_field_attribute("LazyInit", &lazyinit_hooks, NULL);
unassigned_val = newSV(0);
( run in 1.200 second using v1.01-cache-2.11-cpan-5623c5533a1 )