More erlang idioms.

2008-05-02

I received some answers from my previous post about the erlangish way to write some common idioms.

keyword arguments

In response to the analogous Erlang approach for Python's kwargs, ppolv suggested:

albums_create(Title) -> albums_create(Title,[]).
albums_create(Title, Opts) -> [..]
% where Opts = [Opt]
% Opt = {description, Description} | {public, Public} …

which looking through the ibrowse source does indeed seem to be the Erlang way. It was also suggested a record could be used but the Options list seems more idiomatic.

case versus pattern matching function headers

Using pattern matching in function headers is preferred to the case statement. So

init({login_with_hash, ApiKey, UserId, PasswordHash}) ->
  login([
    {"method", "smugmug.login.withHash"},
    {"APIKey", ApiKey},
    {"UserID", UserId},
    {"PasswordHash", PasswordHash}
  ]);
init({login_anonymously, ApiKey}) ->
  login([
    {"method", "smugmug.login.anonymously"},
    {"APIKey", ApiKey}
  ]).

is preferred to

init(Params) ->
  Q = case Params of
  {login_with_hash, ApiKey, UserId, PasswordHash} ->
    [
      {"method", "smugmug.login.withHash"},
      {"APIKey", ApiKey},
      {"UserID", UserId},
      {"PasswordHash", PasswordHash}
    ];
  {login_anonymously, ApiKey} ->
    [
      {"method", "smugmug.login.anonymously"},
      {"APIKey", ApiKey}
    ]
  end,
  login(Q).

One thing I've noticed is the lack of line numbers in the stack trace lends itself to writing functions as small as possible so it's easier to debug the exact origin of the error.

file naming and structure convention

Originally, I grouped both my public API and the application behaviour code in one file, erlsmug.erl. It was recommended I split the two, which made sense to me. Now there is an erlsmug_app.erl for the application behaviour callbacks and erlsmug.erl for the public client API — this was easy. What wasn't easy was trying to debug why my application would no longer start after making the change. The solution turned out to be changing the line

{mod, {erlsmug, []}}

to

{mod, {erlsmug_app, []}}

in my ebin/erlsmug.app file which I had completely forgotten about. The only indication from the Erlang runtime was something about "bad return value" which wasn't, um, obvious to me. Once I fixed the .app file I was golden again.

Categories: development 
Tags: erlang  python 
comments powered by Disqus