Skip to content

Instantly share code, notes, and snippets.

@felher
Last active December 17, 2015 00: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 felher/a8ff211b6f47c9e84024 to your computer and use it in GitHub Desktop.
Save felher/a8ff211b6f47c9e84024 to your computer and use it in GitHub Desktop.
masaks workshop
my @data = (
{ song => "Follow Me Back Into The Sun", duration => "4:18" },
{ song => "The City And The River", duration => "4:02" },
{ song => "Stay Over", duration => "3:17" },
{ song => "Stranger Keeper", duration => "3:30" },
{ song => "You're Not Listening", duration => "4:11" },
);
sub to-seconds($string) {
60 * $_[0] + $_[1] given $string.split(':');
}
sub to-text($seconds) {
sprintf "%d:%d", $seconds div 60, $seconds mod 60;
}
sub total(@data) {
[+] @data.map: *.<duration>.&to-seconds;
}
say to-text total @data;
use v6;
class Promise {
enum State <PENDING FULFILLED REJECTED>;
has State $.state = PENDING;
has %!data;
submethod BUILD(:$!state, :$value) {
%!data{$_}<callbacks> = [] for State.enums.keys;
%!data{$!state}<value> = $value if $value;
}
multi method new() {
self.bless(*, state => PENDING);
}
multi method new(:$state!, :$value where {$state == FULFILLED}) {
die "FULFILLED requires a value-parameter" unless defined $value;
self.bless(*, :$state, :$value);
}
multi method new(:$state!, :reason($value) where {$state == REJECTED}) {
die "REJECTED requires a reason-parameter" unless defined $value;
self.bless(*, :$state, :$value);
}
has Promise method !execute-actions() {
$_(%!data{$!state}<value>) for %!data{$!state}<callbacks>.splice;
self;
}
has Promise method !action($action-state, $action-value) {
return self unless $!state == PENDING;
$!state = $action-state;
%!data{$action-state}<value> = $action-value;
self!execute-actions();
}
has Promise method fulfill($value) { self!action(State::FULFILLED, $value); }
has Promise method reject($reason) { self!action(State::REJECTED, $reason); }
has Promise method then(Callable $on-fulfillment?, Callable $on-rejection?) {
%!data{State::FULFILLED}<callbacks>.push: $on-fulfillment if $on-fulfillment;
%!data{State::REJECTED }<callbacks>.push: $on-rejection if $on-rejection;
self!execute-actions();
}
}
use Test;
my $pen = state => Promise::State::PENDING;
my $ful = state => Promise::State::FULFILLED;
my $rej = state => Promise::State::REJECTED;
my $rea = reason => 'because I say so';
my $val = value => 'yay';
#Test constructors
{
lives_ok { Promise.new(); }, "Can create a Promise with an empty .new";
lives_ok { Promise.new(|$pen) }, "Can create a Promise with an state=>pending";
dies_ok { Promise.new(|$ful) }, "Can not create a FULFILLED promise wihtout a value";
dies_ok { Promise.new(|$rej) }, "Can not create a REJECTED promise wihtout a reason";
lives_ok { Promise.new(|%($rej, $rea)) }, "Can create a Promise Rejected with reason";
lives_ok { Promise.new(|%($ful, $val)) }, "Can create a Promise Fulfilled with a value";
}
#Test eventhandling
{
my Promise $promise .= new;
my $value= "";
$promise.then( { $value= $^x } );
ok !$value, "Hasn't been fulfilled yet";
$promise.fulfill("OH HAI");
is $promise.state, "FULFILLED", "Correct state";
is $value, "OH HAI", "Code has been run";
}
{
my Promise $promise .= new(|%($ful, $val));
is $promise.state, "FULFILLED", "Already correct state";
my $value;
$promise.then( { $value= $^x } );
is $value, "yay", "Code ran immediately";
}
{
my Promise $promise .= new;
my $value= 0;
my $reason= 0;
$promise.then( { $value= $^x }, { $reason= $^x } );
ok !$reason, "Hasn't been rejected yet";
$promise.reject("OH NOES");
is $promise.state, "REJECTED", "Correct state";
ok !$value, "Fulfill code didn't run";
is $reason, "OH NOES", "Reject code has been run";
}
{
my Promise $promise .= new;
my $value = 0;
$promise.then( { $value++ } );
$promise.then( { $value++ } );
$promise.then( { $value++ } );
ok !$value, "Hasn't been fulfilled yet";
$promise.fulfill("OH HAI");
$promise.then( { $value++ } );
is $promise.state, "FULFILLED", "Correct state";
is $value, 4, "Code has been run";
}
done();
use v6;
my @steps =
1000, 'M', 900, 'CM',
500, 'D', 400, 'CD',
100, 'C', 90, 'XC',
50, 'L', 40, 'XL',
10, 'X', 9, 'IX',
5, 'V', 4, 'IV',
1, 'I',
;
sub to_roman(Int $number is copy) {
[~] do for @steps -> $step, $symbol {
[$symbol x $number div $step, $number mod= $step][0] if $step <= $number;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment