```{index} single: wizard; Peta::XS function ``` ```{index} single: Peta::XS::wizard; Perl function ``` # wizard Create a wizard: an opaque bundle of magic callbacks. ## Synopsis ```perl 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`](cast), [`dispell`](dispell) and [`getdata`](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`](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 ```perl ## 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`](cast) - attach the wizard to a variable. - [`getdata`](getdata) - read an attachment's private data back. - [`magic`](magic) - the facts-side view of an attachment.