wizard#

Create a wizard: an opaque bundle of magic callbacks.

Synopsis#

use Peta::XS ':magic';
my $w = wizard(
    get  => sub { my ($ref, $data) = @_; ... },
    set  => sub { my ($ref, $data) = @_; ... },
    free => sub { my ($ref, $data) = @_; ... },
    data => sub { my ($ref, @args) = @_; return { count => 0 } },
);

What you get back#

An opaque handle. Hold it, pass it to cast, dispell and getdata - nothing else. One wizard can be cast on any number of variables; each attachment gets its own private data.

Contract#

All keys are optional but at least one of get/set/free is required; every value must be a code reference (anything else croaks, as does an unknown key). get is called before the variable’s value is used, set after it changed, free while it is being destroyed; each receives (\$var, $data) and its return value is ignored (no value substitution in v1). data is called once per cast to build that attachment’s private data. A callback that dies propagates exactly like a dying tied-variable FETCH/STORE. A variable carrying wizard magic is never JIT-compiled, so callbacks fire on every single access, compiled neighbors notwithstanding.

Examples#

## a watchpoint: who is touching $config?

my $watch = wizard(
    get => sub { warn "read at @{[ join ':', caller ]}\n" },
    set => sub { warn "now: ${$_[0]}\n" },
);

## lazy initialization: get may write the variable before the

## pending read uses it (magic is suspended inside callbacks, so

## this does not recurse)

my $lazy = wizard(get => sub { ${$_[0]} //= expensive() });
my $val;
cast(\$val, $lazy);
say $val;                 # expensive() runs here, exactly once
say $val;                 # cached now

## per-attachment counters via a data callback

my $counted = wizard(
    data => sub { { reads => 0, writes => 0 } },
    get  => sub { $_[1]{reads}++ },
    set  => sub { $_[1]{writes}++ },
);

See also#

  • cast - attach the wizard to a variable.

  • getdata - read an attachment’s private data back.

  • magic - the facts-side view of an attachment.