Комментарии 15
Лучше предусмотреть возможность использования модуля в ООП режиме. Хотя для учебного материала это не особо нужно :)
предусмотрел :)
ok 1 — two modes
ok 2 — fib(100)
package MyMath; our $VERSION = '0.01'; use strict; use bigint; use Recurrent; sub new { bless {}, shift; } recurrent 'fib' => { arg(0) => lambda { my($n) = @_; return 0 }, arg(1) => lambda { my($n) = @_; return 1 }, arg(n) => lambda { my($n) = @_; return fib($n-1) + fib($n-2) }, }; 1;
#!/usr/bin/perl -I./lib use strict; use bigint; use Test::More tests => 2; use MyMath; is(MyMath->new->fib(100), MyMath::fib(100), "two modes"); is(MyMath->new->fib(100), 354224848179261915075, "fib(100)");
ok 1 — two modes
ok 2 — fib(100)
Магия
И все-таки лучше просто писать на Erlang.
Я бы использовал confess, вместо croak, раз речь идёт и ловле ошибок программиста, а не юзера.
Так же lambda вместо sub — это уже дело вкуса… Мне вполне нравится sub, кстати в perl 5.10 часто можно просто поставить скобки {}.
Ещё, раз функция может быть от одной переменной, я бы использовал local $_, код тогда мог выглядеть так:
$_ удобна тем что многие встроенные функции можно вызывать с этим неявным аргументом — defined, /someregexp/ chomp итд.
Передать $_ в функцию можно просто:
Так же lambda вместо sub — это уже дело вкуса… Мне вполне нравится sub, кстати в perl 5.10 часто можно просто поставить скобки {}.
Ещё, раз функция может быть от одной переменной, я бы использовал local $_, код тогда мог выглядеть так:
arg(0) => sub { 0 },
arg(1) => sub { 1 },
arg(n) => sub { fib($_-1) + fib($_-2) },
$_ удобна тем что многие встроенные функции можно вызывать с этим неявным аргументом — defined, /someregexp/ chomp итд.
Передать $_ в функцию можно просто:
$mycallback->() for ($myarg);
Ещё из косметики — когда присваиваем глобу анонимную ф-цию, я обычно делаю такую штуку:
Очень помогает при отладке видеть, что упало не в некоей __ANON__, которых может быть 3-4 подряд по стеку, а именно в foo().
use Sub::Name;
*foo = subname foo => sub{};
Очень помогает при отладке видеть, что упало не в некоей __ANON__, которых может быть 3-4 подряд по стеку, а именно в foo().
use v5.14;
use Memoize;
use List::Util qw(sum reduce);
memoize 'fib';
say sum map fib($_), 1..100; # "sum" is a "reduce { $a + $b }"
sub fib {
my $n = shift;
return $n if $n < 2;
fib($n-1) + fib($n-2);
}
Да, только хотел про Memoize написать :) Очень полезная штука.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Вычисление рекуррентных соотношений на Perl