Pull to refresh

Erlang декораторы

Reading time1 min
Views1.9K
Иногда не хватает в Erlang этой интересной особенности, вот и захотелось мне в заиметь эту фичу.

Поискав по просторам интернета наткнулся на статью.

Автор практически полностью реализовал весь функционал кроме передачи аргументов декоратору.

Сразу дам ссылку на Github.

Итак, отличие моего проекта — декоратору можно прередать праметры и опцию verbose, благодаря которой 3-м аргументом в декоратор будет передан кортеж с именем функции и строкой в файле.

Пример использования, который использует обе эти особенности (конечно не production, но суть должна быть ясна).

-module(memoize).

% This row is required for decorators
-compile([{parse_transform,decorators}]).

% exporting decorator function
-export([memoize/4]).

% api exports
-export([fact/1]).

% pretty decorator usage
-define(MEMOIZE, -decorate({?MODULE,memoize,[?MODULE],verbose})).

memoize(F,Args,{FunName,_Line},Module)->
    case ets:info(memoize) of
        undefined ->
            ets:new(memoize,[public,named_table]);
        _->
            ok
    end,
    case ets:lookup(memoize,{Module,FunName,Args}) of
        [] ->
            R = apply(F,[Args]),
            ets:insert(memoize,{{Module,FunName,Args},R}),
            R;
        [{_,Value}] ->
            Value
    end.

?MEMOIZE. % decorator
fact(N) when is_integer(N) andalso N>=1  ->
    fact(N,1).

fact(1,Acc) -> Acc;
fact(N,Acc) -> fact(N-1,Acc*N).


Ну и тест 2-х вызовов:

>> timer:tc(memoize,fact,[1000]).
{1282,
  ... }.

>> timer:tc(memoize,fact,[1000]).
{9,
  ... }.


Т.е. прирост заметен :)

Не хочу разводить холивар на тему нужно это или нет, просто буду рад, если кому пригодится…

P.S.
Если кому будет интересно — могу в дальнейшем полностью описать весь процесс кодогенерации через parse_transform…
Tags:
Hubs:
+11
Comments11

Articles

Change theme settings