Skip to content

Instantly share code, notes, and snippets.

@peczenyj
Last active January 4, 2016 09:39
Show Gist options
  • Select an option

  • Save peczenyj/8603573 to your computer and use it in GitHub Desktop.

Select an option

Save peczenyj/8603573 to your computer and use it in GitHub Desktop.
An example of frequency iterator
use strict;
use warnings;
package Frequency::Iterator;
# ABSTRACT: Module who abstract a frequency iterator
use Exporter 'import';
use Carp qw(croak);
use List::MoreUtils qw(any natatime pairwise);
our @EXPORT_OK=qw(freq_it);
sub freq_it {
my ($frequency, $values) = @_;
croak "frequency and values should had the same size"
unless scalar(@$frequency) == scalar(@$values);
croak "frequency should be an array of positive numbers"
if any { $_ < 0 } @$frequency;
natatime 1, pairwise { our($a,$b); ($a) x int($b) } @$values, @$frequency
}
package main;
use Test::More tests => 4;
use Test::Exception;
subtest "prepare" => sub {
my $it = Frequency::Iterator::freq_it([1,0,2] => [4,9,5]);
ok ref($it), 'should return a reference';
is $it->(), 4, 'should return 4 #1';
is $it->(), 5, 'should return 5 #2';
is $it->(), 5, 'should return 5 again #3';
ok !$it->(), 'should reach the end';
};
subtest "prepare should coerce frequency to integer" => sub {
my $it = Frequency::Iterator::freq_it([1,0,2.1] => [4,9,5]);
ok ref($it), 'should return a reference';
is $it->(), 4, 'should return 4 #1';
is $it->(), 5, 'should return 5 #2';
is $it->(), 5, 'should return 5 again #3';
ok !$it->(), 'should reach the end';
};
subtest "verify difference in size" => sub {
throws_ok {
Frequency::Iterator::freq_it([1,0,2,2] => [4,9,5]);
}
qr/frequency and values should had the same size/,
'shuold die with proper message'
};
subtest "verify difference in size" => sub {
throws_ok {
Frequency::Iterator::freq_it([1,0,-2] => [4,9,5]);
}
qr/frequency should be an array of positive numbers/,
'shuold die with proper message'
};
__END__
=head1 NAME
Frequency::Iterator - Module who abstract a frequency iterator
=head1 SYNOPSIS
use Frequency::Iterator 'freq_it';
my $it = freq_it([1,0,2] => [4,9,5]);
while (my $v = $it->()) {
say $v;
}
should print 4, 5, 5
=head1 DESCRIPTION
This module exposes one frequency iterator.
=head2 freq_it
This subroutine receive two arrayrefs, one with frequency and another with values.
The first element in frequency array tells how many times we should return the first
element of values, then we move to the next element. In the end we return an false value.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment