-FUNCTIONS
- "wizard"
- wizard sig => ...,
- data => sub { ... },
- get => sub { my ($ref, $data) = @_; ... },
- set => sub { my ($ref, $data) = @_; ... },
- len => sub { my ($ref, $data, $len) = @_; ... ; return $newlen; },
- clear => sub { my ($ref, $data) = @_; ... },
- free => sub { my ($ref, $data) = @_, ... },
- copy => sub { my ($ref, $data, $key, $elt) = @_; ... },
- local => sub { my ($ref, $data) = @_; ... },
- fetch => sub { my ($ref, $data, $key) = @_; ... },
- store => sub { my ($ref, $data, $key) = @_; ... },
- exists => sub { my ($ref, $data, $key) = @_; ... },
- delete => sub { my ($ref, $data, $key) = @_; ... }
+ "VMG_COMPAT_HASH_DELETE_NOUVAR_VOID"
+ True for perls that don't call 'delete' uvar magic when you delete an
+ element from a hash in void context.
+
+ "VMG_COMPAT_GLOB_GET"
+ True for perls that call 'get' magic for operations on globs.
+
+ "VMG_PERL_PATCHLEVEL"
+ The perl patchlevel this module was built with, or 0 for non-debugging
+ perls.
+
+ "VMG_THREADSAFE"
+ True iff this module could have been built with thread-safety features
+ enabled.
+
+ "VMG_FORKSAFE"
+ True iff this module could have been built with fork-safety features
+ enabled. This will always be true except on Windows where it's false for
+ perl 5.10.0 and below .
+
+ "VMG_OP_INFO_NAME"
+ Value to pass with "op_info" to get the current op name in the magic
+ callbacks.
+
+ "VMG_OP_INFO_OBJECT"
+ Value to pass with "op_info" to get a "B::OP" object representing the
+ current op in the magic callbacks.
+
+COOKBOOK
+ Associate an object to any perl variable
+ This technique can be useful for passing user data through limited APIs.
+ It is similar to using inside-out objects, but without the drawback of
+ having to implement a complex destructor.
+
+ {
+ package Magical::UserData;
+
+ use Variable::Magic qw<wizard cast getdata>;
+
+ my $wiz = wizard data => sub { \$_[1] };
+
+ sub ud (\[$@%*&]) : lvalue {
+ my ($var) = @_;
+ my $data = &getdata($var, $wiz);
+ unless (defined $data) {
+ $data = \(my $slot);
+ &cast($var, $wiz, $slot)
+ or die "Couldn't cast UserData magic onto the variable";
+ }
+ $$data;
+ }
+ }
+
+ {
+ BEGIN { *ud = \&Magical::UserData::ud }
+
+ my $cb;
+ $cb = sub { print 'Hello, ', ud(&$cb), "!\n" };
+
+ ud(&$cb) = 'world';
+ $cb->(); # Hello, world!
+ }
+
+ Recursively cast magic on datastructures
+ "cast" can be called from any magical callback, and in particular from
+ "data". This allows you to recursively cast magic on datastructures :
+
+ my $wiz;
+ $wiz = wizard data => sub {
+ my ($var, $depth) = @_;
+ $depth ||= 0;
+ my $r = ref $var;
+ if ($r eq 'ARRAY') {
+ &cast((ref() ? $_ : \$_), $wiz, $depth + 1) for @$var;
+ } elsif ($r eq 'HASH') {
+ &cast((ref() ? $_ : \$_), $wiz, $depth + 1) for values %$var;
+ }
+ return $depth;
+ },
+ free => sub {
+ my ($var, $depth) = @_;
+ my $r = ref $var;
+ print "free $r at depth $depth\n";
+ ();
+ };
+
+ {
+ my %h = (
+ a => [ 1, 2 ],
+ b => { c => 3 }
+ );
+ cast %h, $wiz;
+ }
+
+ When %h goes out of scope, this will print something among the lines of
+ :
+
+ free HASH at depth 0
+ free HASH at depth 1
+ free SCALAR at depth 2
+ free ARRAY at depth 1
+ free SCALAR at depth 3
+ free SCALAR at depth 3
+
+ Of course, this example does nothing with the values that are added
+ after the "cast".