Как я могу оптимизировать это? - PullRequest
2 голосов
/ 25 октября 2011

Я сейчас учусь кодировать Erlang.У меня есть веб-приложение поверх Chicago Boss.У меня есть модель с именем Todo, и я хотел бы предложить CRUD-операции с ней в качестве REST API.

В моем методе PUT у меня есть такой код:

index('PUT', [Id]) ->
    Todo = boss_db:find(Id),
    Body = element(2, mochijson:decode(Req:request_body())),
    %% Set the new values
    NewTodo = Todo:attributes([
            {subject, proplists:get_value("subject", Body)},
            {done, proplists:get_value("done", Body)}
        ])
,
    {json, [{todo, element(2, NewTodo:save())}]}.

Как я могу оптимизироватьэтот фрагмент кода?Или это уже лучший вариант?

Есть ли какой-нибудь "умный" способ изменить ключи проплиста на ключи атома?Например:

[{"subject", "Foo"}] -> [{subject, "Foo"}].

Я также считаю утомительным присваивать переменную Todo, а затем иметь NewTodo.К сожалению, я не могу найти хороший пример приложений Erlang Chicago Boss на github, которые я могу проверить.

Ответы [ 3 ]

1 голос
/ 25 октября 2011

Вы всегда можете сделать что-то вроде этого:

t([{"subject", V}|T]) -> [{subject, V}|t(T)];
t([{"done"   , V}|T]) -> [{done,    V}|t(T)];
t([_             |T]) ->               t(T) ; % optional garbage ignoring clause
t([])                 -> [].

Но я сомневаюсь, это будет значительное улучшение скорости в вашем случае.

Может быть, вы сможете выжать последний бит изэто:

-compile({inline, [t/1]}).
t(L) -> t(L, []).

t([{"subject", V}|T], A) -> t(T, [{subject, V}|A]);
t([{"done"   , V}|T], A) -> t(T, [{done,    V}|A]);
t([_             |T], A) -> t(T, A); % optional garbage ignoring clause
t([], A)                 -> A.

Что стоит только для соревнований по тестированию кода ;-) (Обратите внимание, что в последнем предложении нет вызова lists:reverse/1. Это приведет к разрушению улучшения из предыдущей версии.)

PS: Если вы думаете, что я фанат микро-оптимизации, вы правы, поэтому я бы заменил lists:reverse/1 call на lists:reverse/2, чтобы напрямую использовать BIF и сэкономить еще немного времени; -)

0 голосов
/ 26 декабря 2012

Как насчет

index('PUT', [Id]) ->
    Body = element(2, mochijson:decode(Req:request_body())),
    OldTodo = boss_db:find(Id),
    NewTodo = OldTodo:attributes([ {list_to_atom(A),B} || {A,B}<-Body ]),
    {json, [{todo, element(2, NewTodo:save())}]}.
0 голосов
/ 26 декабря 2012

К сожалению, я не могу комментировать ответ Хайнека, но, как новичок Эрланга, я бы предпочел сделать что-то вроде:

lists:map(fun({A, B}) -> {list_to_atom(A), B} end, [X || {Y, Z}=X <- List, is_list(Y)]).

Вы действительно не можете избежать назначения NewTodo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...