[erlang-questions] Module config data and functional programming

Per Melin per.melin@REDACTED
Fri Apr 22 11:34:21 CEST 2011

On Thu, Apr 21, 2011 at 8:54 PM, Daniel Dormont
<dan@REDACTED> wrote:
> start(Host, Opts) -> ejabberd_hooks:add(some_hook, global, ?MODULE, some_function).
> stop(Host) -> ejabberd_hooks:delete(some_hook, global, ?MODULE, some_function).
> some_function(List) -> lists:filter(fun my_filter/1, List).
> my_filter(Value) -> %complex logic here%
> The idea being that the module can be initialized with some options that were passed from a config file. FYI, ejabberd_hooks is used to register and unregister callbacks for certain events.
> What I have above works fine, but now I'm in a situation where my_filter needs access to data that came from Opts.

I've never used ejabberd but I peeked at the documentation for
ejabberd_hooks:add/3,4,5 and it looks like you can also give it a fun.
So a closure could carry the value of Opts for you:

start(_Host, Opts) -> ejabberd_hooks:add(some_hook, make_hook_fun(Opts), 1).

make_hook_fun(Opts) ->
    fun(List) ->
        lists:filter(fun(Value) -> my_filter(Value, Opts) end, List)

my_filter(Value, Opts) -> %complex logic here%

The problem then becomes your stop function since
ejabberd_hooks:delete/3,4,5 needs to be passed the exact same fun it
seems. You would need to either hold on to the return value of
make_hook_fun(Opts) or the Opts themselves and pass that to the stop

There is also the issue of code updates. If ejabberd stores your fun
in an ETS table and you reload your module with a different version of
make_hook_fun/1 then the fun in ETS will crash the next time it is

More information about the erlang-questions mailing list