2011-10-25 2 views
2

J'apprends actuellement à coder Erlang. J'ai une application web sur Chicago Boss. J'ai un modèle appelé Todo, et je voudrais proposer des opérations CRUD comme API REST.Comment puis-je optimiser cela?

Dans ma méthode PUT Je possède ce code:

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())}]}. 

Comment puis-je optimiser ce fragment de code? Ou est-ce déjà le meilleur possible?

Existe-t-il un moyen plus "intelligent" de changer les clés d'une liste de biens en clés atomiques? Comme ceci:

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

Je trouve aussi genre de fastidieux d'assigner une variable Todo puis un NewTodo. Malheureusement, je ne peux pas trouver de bons exemples d'applications Erlang Chicago Boss sur github que je peux vérifier.

+0

Désolé mais que fait la fonction element()? Je suis nouveau à cela. :) –

Répondre

1

Vous pouvez toujours faire quelque chose comme ceci:

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([])     -> []. 

Mais je doute, ce sera une amélioration significative de la vitesse dans votre cas.

Peut être que vous pourrez presser dernière partie de ceci:.

-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. 

Ce qui ne vaut que pour les compétitions de code de référence ;-) (Notez qu'il n'y a pas lists:reverse/1 appel à la dernière clause Ce serait ruiner l'amélioration former version précédente)

PS. Si vous pensez que je suis maniaque micro-optimisation, vous avez raison, donc je remplacerais lists:reverse/1 appel avec lists:reverse/2 utiliser BIF directement et économiser plus de temps ;-)

+1

C'est mieux que d'utiliser 'proplist' car vous ne passez qu'une fois sur la liste. – rvirding

0

Malheureusement, je ne peux pas commenter la réponse de Hynek, mais comme novice Erlang, ma première estimation aurait été d'aller chercher quelque chose le long des lignes de:

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

Vous ne pouvez pas vraiment éviter l'affectation NewTodo

0

Comment à propos de

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())}]}.