taiyoh's memorandum

@ttaiyoh が、技術ネタで気づいたことを書き溜めておきます。

Sub::Deferredなんてモジュール書いてみた

 最近、全然ブログ書いてないな、と思ったのですが、よくよく考えると、今年に入ってコード全然書いてなかったわけで、こりゃちょっといかん、と思いまして。
 リハビリついでに、jQuery1.7の$.Deferredの機能をなるべくほぼそのままPerlに移植してみました。完全じゃないけど。
 → taiyoh/p5-Sub-Deferred · GitHub
 これを使うと、

#!perl

use strict;
use warnings;
use utf8;

use FindBin;
use Perl6::Say;

use Sub::Deferred;
use AnyEvent;

my $cv = AE::cv;
my @defs = map { Sub::Deferred->new } 1 .. 3;
my $when = Sub::Deferred->when(@defs);
my $foo = 2;
my @timers = map {
    my $def = $_;
    my $sec = int(rand 5) + 1;
    AE::timer $sec, 0, sub {
        say "$sec sec after";
        $foo *= 2;
        $def->resolve;
    };
} @defs;
$when->done(sub {
    $foo *= 3;
    $cv->send($foo);
});

say "result: ". $cv->recv; # => 48

 こんな感じで、「あれ、なんかjQueryで見たことある書き方」みたいなことができるようになります。CPANにはObject::Deferredとかいうモジュールもあるのですが、機能が少ない上にそれのためにMoose使うってなんじゃ、と思ったもので。
 一応依存モジュールもなく Pure Perlで、5.8.8以降で動くはずですが、真っ当な方はData::Monadを応援するか、Coroを使いこなす方がいいと思います!