Skip to content

Instantly share code, notes, and snippets.

@gugod
Last active May 23, 2023 01:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gugod/1955842587cfea2ec78b7bb533c6e4ed to your computer and use it in GitHub Desktop.
Save gugod/1955842587cfea2ec78b7bb533c6e4ed to your computer and use it in GitHub Desktop.
use v5.36;
use JSON ();
use Data::Dumper qw(Dumper);
package DieMan {
sub new ($class, $res = [], $err = undef) {
bless { "res" => $res, "err" => $err }
}
sub res ($self) { $self->{"res"} }
sub err ($self) { $self->{"err"} }
sub then ($self, $sub) {
return $self if $self->{"err"};
my (@newRes, $error);
eval {
@newRes = $sub->(@{ $self->{"res"} });
1;
} or do {
$error = $@;
};
if (defined $error) {
return DieMan->new( $self->{"res"}, $error );
}
return DieMan->new( \@newRes, undef );
}
}
sub MayDie {
my ($res, @subs) = @_;
return (undef, $res) unless @subs;
my $sub = shift(@subs);
my (@newRes, $error);
eval {
@newRes = $sub->(@$res);
1;
} or do {
$error = $@;
};
if (defined $error) {
return ($error, $res);
}
return MayDie( \@newRes, @subs );
}
sub callAPI($url) {
warn "callAPI: $url";
# die "Failed at calling $url";
# return +{};
return +{
"body" => '{"foo":1}'
}
}
sub decodeJsonBody($res) {
warn "decode: $res -> $res->{body}";
JSON->new->decode($res->{"body"})
}
my $res = DieMan->new(["https://example.com"])
->then( \&callAPI )
->then( \&decodeJsonBody );
say Dumper([ "DieMan", $res->err, $res->res ]);
my ($error, $result) = MayDie(
["https://example.com"],
\&callAPI,
\&decodeJsonBody,
);
say Dumper([ "MayDie", $error, $result ]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment