Data::Postponed - Delay the evaluation of expressions to allow post facto changes to input variables
Postponing changes with postpone()
use Data::Postponed 'postpone'; %functions = ( foobar => 'foo' ); $code = "sub " . postpone( $functions{foobar} ) . " { return time }"; $functions{foobar} = "baz"; # Reflects the new name of 'bar' instead of 'foo'; print $code; # Will throw an error because 'foobar' can't be renamed anymore. $functions{foobar} = 'baz';
Postponing changes with postpone_once()
use Data::Postponed 'postpone_once'; %functions = ( foobar => 'foo' ); $code = "sub " . postpone_once( $functions{foobar} ) . " { return time }"; $functions{foobar} = "baz"; # Reflects the new name of 'bar' instead of 'foo'. $code isn't # overloaded anymore. print $code; # The change to $functions{foobar} is no longer reflected in $code $functions{foobar} = "quux"; print $code;
Postponing changes with postpone_forever()
use Data::Postponed 'postpone_forever'; %functions = ( foobar => 'foo' ); $code = "sub " . postpone_forever( $functions{foobar} ) . " { return time }"; $functions{foobar} = "baz"; # Reflects the new name of 'bar' instead of 'foo'; print $code; # Continues to reflect changes to the input variables $functions{foobar} = "quux"; print $code;
This module allows you to delay the computation of values, usually so you can change your mind about the returned value. Its a sort of time travel.
The values returned by this module are overloaded objects which can be operated on like numbers, strings, or booleans but aren't actually made "real" until you use them in some context that requires that they be computed first.
As an aide to debugging and to prevent time paradoxes, the default
postpone() function's effect is that once a value has been computed,
it ceases to be overloaded and all of the input variables to it are
turned read only.
This method must be overridden by a subclass. Data::Postponed comes with three subclasses: the Data::Postponed::OnceOnly manpage, the Data::Postponed::Once manpage, the Data::Postponed::Forever manpage each of which override this method.
Calling Data::Postponed-new( ... )> directly will produce an error.
Clone()
This method returns a new Data::Postponed object in the same subclass
equivalent to the current object. This implements the = method for
the overload manpage.
Each of the methods bool, "", 0+ may be overridden. The base
class implementation evaluates all of the delayed computation with no
side effects and returns the computed value. If these methods are not
overridden, an overloaded value may be evaluated again in the future
and its result may be different.
The the Data::Postponed::Forever manpage subclass does exactly this. No overriding occurs and repeated evaluation of the overloaded value always recalculates the returned value.
The the Data::Postponed::Once manpage subclass overrides the conversion methods so that once the value has been computed, it is finalized and will not be recomputed again in the future.
The the Data::Postponed::OnceOnly manpage subclass is the Data::Postponed::Once manpage except that it marks all of its input variables as read only after this finalization has occurred. This provides you with an extra level of security.
If you have a bug in your code and write to an input variable after the postponed value has already been computed, you will receive an error from perl that you have attempted to write to a read only variable.
All of the methods listed in the with_assign, num_comparison,
3way_comparison, str_comparison, binary values of the
%overload::ops hash. Also, the atan2 method from func.
The cos, sin, exp, abs, log, sqrt methods from
func, the unary, and the iterators values of the
%overload::ops hash.
All of the methods listed in the assign value of the
%overload::ops hash.
The mutator methods from %overload::ops.
The function Data::Postponed::Dump may be called on a
Data::Postponed object / expression to produce a dump of the structure
of a postponed object. It is pseudo-lisp.
When called in void context, it prints its output to the currently selected filehandle, normally STDOUT.
When called in scalar or list context, it returns its output as a string.
Data::Postponed enables assertions if the environment variable
DATA_POSTPONED_DEBUG is true, if $^P is true, or if perl was invoked
with the -d parameter.
If the module the Carp::Assert manpage cannot be loaded, assertions are not enabled.
Data::Postponed uses the Carp manpage::cluck() to report the execution and
progress of the module.
If the module the Data::Dump::Streamer manpage can be loaded, some values will be dumped as well.
This is really similar to the Really symbolic calculator from the the overload manpage documentation. This expands on that idea by adding the ::Once and ::OnceOnly subclasses and taking care to be generalized instead of for just arithmetic.
Joshua ben Jore, <jjore@cpan.org>
Please report any bugs or feature requests to
bug-data-postponed@rt.cpan.org, or through the web interface at
http://rt.cpan.org/NoAuth/ReportBug.html. I
will be notified, and then you'll automatically be notified of
progress on your bug as I make changes.
Corion of perlmonks.org
Copyright 2005 Joshua ben Jore, All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.