Dado que a solução com recursão tinha duas funções bem parecidas, o natural é subir um nível na abstração e criar uma função para criar funções.
#!/usr/bin/perl
use strict;
use warnings;
no warnings 'recursion';
sub make_fizzbuzz {
my ($callback, $factor, $word)=@_;
return sub {
my $n=shift || 1;
my $multiple=shift || 0;
if($n % $factor == 0) {
print $word;
$multiple=1;
}
$callback->($n, $multiple);
}
}
my $fizzbuzz;
$fizzbuzz=make_fizzbuzz(make_fizzbuzz(sub {
my ($n, $multiple)=@_;
print $n if !$multiple;
print "\n";
$fizzbuzz->($n+1) if $n<1000;
}, 5, 'buzz'), 3, 'fizz');
$fizzbuzz->();
Dado que o código recursivamente cria uma recursão, parece natural começar pelo fim, então a primeira função passada é o caso especial e ela também é uma closure, porque precisa referenciar o ponto de partida.
Depois disso, podemos adicionar mais casos facilmente:
$fizzbuzz=make_fizzbuzz(make_fizzbuzz(make_fizzbuzz(make_fizzbuzz(sub {
my ($n, $multiple)=@_;
print $n if !$multiple;
print "\n";
$fizzbuzz->($n+1) if $n<1000;
}, 5, 'buzz'), 3, 'fizz'), 7, 'crackle'), 11, 'pop');
Bem elegante, na minha opinião.
Nenhum comentário:
Postar um comentário