⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 promise.pm

📁 1. 记录每个帖子的访问人情况
💻 PM
字号:
# Copyright 2001-2005 Six Apart.# SCRiPTMAFiA 2005 - THE DiRTY HANDS ON YOUR SCRiPTS## $Id: Promise.pm 10802 2005-03-29 02:46:37Z ezra $package MT::Promise;use strict;use Exporter;*import = \&Exporter::import;@MT::Promise::EXPORT_OK = qw(delay force lazy);sub new {    my ($class, $code) = @_;    my $this = \$code;    bless $this, $class;}sub delay {    my ($this) = @_;    __PACKAGE__->new($this);}sub lazy (&) {    my ($this) = @_;    __PACKAGE__->new($this);    }sub force {    my ($this) = @_;    return $this if (ref $this ne 'MT::Promise');    if (ref $$this eq 'CODE') {	$$this = $$this->();    } else {	return $$this;    } }1;__END__=head1 NAMEMT::Promise - Faux-lazy evaluation for Perl=head1 SYNOPSIS    sub work_hard {        # some costly operation    }    use MT::Promise qw(delay lazy force);    # slickest    $meaning_of_life = lazy { work_hard(); return 42 };    # kinda slick    $meaning_of_life = delay(sub { work_hard(); return 42 });    # clunky ...    $meaning_of_life = new MT::promise(sub { work_hard(); return 42; });    print force($meaning_of_life);    # prints:    # 42    =head1 DESCRIPTIONA promise is like a value, but the value itself hasn't been computedyet. At any time, you can "force" the promise to get its value; thefirst time it's forced, the computation of the value takes place andthe value is stored. Thereafter, forcing it uses the stored valueinstead of re-computing it.This is useful if some bit of code may be expecting a value in acertain place, but you don't know up front whether that value willreally be needed. To use this optimization, the expectant code needsto expect a promise, of course, since it has to call C<force> to getthe value. But you don't have to worry about whether the value will beneeded or which bit of code will need it first--that will shake out atruntime.=head1 USAGEThere are three forms for creating promises. The C<lazy> form is the slickest:    my $red = foo($arg);    my $value = lazy {        $green = green($red);        $blue = blue($red, $green);    }The C<delay> form can be useful if you want to delay the evaluation ofa routine that already has a name:   my $value = delay \&costly_function;but it should be pointed out that costly_function in this case must bea thunk--it must not expect any arguments. Typically, you end upusing a closure or the C<lazy> form to encapsulate the arguments:  my $value1 = lazy { fibonacci(8675309) };This is almost precisely like $value2 = fibonacci(865309) except that(a) you have to force $value1, and (b) the 8675309th fibonacci won'tbe calculated if it's never C<force>d.Last and least, you can use C<new> to create a promise, though it'sclunkier than the other methods:   my $value = new MT::Promise(sub { fibonacci(8675309) });This would be useful if you were sub-classing promise for some reason.=head1 NOTESNote that if you use the name of a variable declared outside the lazyblock, such as    my $red;    my $value = lazy { foo($red) }then $value will carry around a reference to $red for as long as$value lives. This is important to keep in mind as it's possible tocreate a circular reference without realizing it. You've got to trypretty hard, though.=cut

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -