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 )