GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
Data::Thunk(3) User Contributed Perl Documentation Data::Thunk(3)

Data::Thunk - A sneakier Scalar::Defer ;-)

        use Data::Thunk qw(lazy);

        my %hash = (
                foo => lazy { $expensive },
        );

        $hash{bar}{gorch} = $hash{foo};

        $hash{bar}{gorch}->foo; # vivifies the object

        warn overload::StrVal($hash{foo}); # replaced with the value

This is an implementation of thunks a la Scalar::Defer, but uses Data::Swap and assignment to $_[0] in order to leave a minimal trace of the thunk.

In the case that a reference is returned from "lazy { }" Data::Swap can replace the thunk ref with the result ref, so all the references that pointed to the thunk are now pointing to the result (at the same address).

If a simple value is returned then the thunk is swapped with a simple scalar container, which will assign the value to $_[0] on each overloaded use.

In this particular example:

        my $x = {
                foo => lazy { "blah" },
                bar => lazy { [ "boink" ] },
        };

        $x->{quxx} = $x->{foo};
        $x->{gorch} = $x->{bar};

        warn $x->{bar};
        warn $x->{foo};
        warn $x->{quxx};

        use Data::Dumper;
        warn Dumper($x);

The resulting structure is:

        $VAR1 = {
                'bar' => [ 'boink' ],
                'foo' => 'blah',
                'gorch' => $VAR1->{'bar'},
                'quxx' => 'blah'
        };

Whereas with Scalar::Defer the trampoline objects remain:

        $VAR1 = {
                'bar' => bless( do{\(my $o = 25206320)}, '0' ),
                'foo' => bless( do{\(my $o = 25387232)}, '0' ),
                'gorch' => $VAR1->{'bar'},
                'quxx' => $VAR1->{'foo'}
        };

This is potentially problematic because "reftype" in Scalar::Util and "blessed" in Scalar::Util can't be fooled. With Data::Thunk the problem still exists before values are vivified, but not after.

Furthermore this module uses UNIVERSAL::ref instead of blessing to 0. Blessing to 0 pretends that everything is a non ref ("ref($thunk)" returns the name of the package, which evaluates as false), so deferred values that become objects don't appear to be as such.

lazy { ... }
Create a new thunk.
lazy_object { }, %attrs;
Creates a thunk that is expected to be an object.

If the "class" attribute is provided then "isa" and "can" will work as class methods without vivifying the object.

Any other attributes in %attrs will be used to shadow method calls. If the keys are code references they will be invoked, otherwise they will be simply returned as values. This can be useful if some of your object's properties are known in advance.

lazy_new $class, %args;
A specialization on "lazy_object" that can call a constructor method based on a class for you. The "constructor" and "args" arguments (method name or code ref, and array reference) will be removed from %args to create the thunk. They default to "new" and an empty array ref by default. Then this function delegates to "lazy_object".
force
Vivify the value and return the result.

Scalar::Defer, Data::Lazy, Data::Swap, UNIVERSAL::ref.

Yuval Kogman

This software is Copyright (c) 2010 by Yuval Kogman.

This is free software, licensed under:

  The MIT (X11) License
2010-09-10 perl v5.32.1

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.